F# Type Providers and Continuous Integration - f#

The type definition of an F# type provider often requires a constant expression, e.g. for the SQL type provider:
type dbSchema = SqlDataConnection<"Data Source=MySqlServer;Initial Catalog=MyDatabase;">
However, when committing the code to SCM, and further having a build server doing its thing, you probably don’t want to use the same connection string, but rather the connection string of a SQL server database that is generated from the build process.
Is there a solution for this problem?
It would be really nice to be able to make this work, as it would provide a compile-time check of the database access code.
Update
The solution proposed by #tomaspetricek worked very well, but I had to add a provider name to the connection string:
<add name="DbConnectionString" providerName="System.Data.SqlClient" connectionString="Data Source=MySqlServer;Initial Catalog=MyDatabase;"/>

You can certainly specify the connection string using a key in a configuration file (see MSDN documentation):
SqlDataConnection<ConnectionStringName="...", ConfigFile="app.config">
In general, a type provider may require some constant expression, but I think most of the widely used ones provide a way for avoiding this. For example, SqlDataConnection can read the setting from configuration file, other standard F# type providers allow specifying LocalSchemaFile that allows you to specify the necessary structure locally (e.g. *.dbml file for SQL).
The F# Data type providers can take URL to a remote file, but they can also take local file. So I think that there should always be a way to specify the information without specifying a constant connection string (etc.) - but feel free to ask about specific providers.

Related

Is it possible to open a namespace provided by a Type Provider?

Is there any way to open a namespace of types provided by a type provider implementation? I ask, because some of the generated type name paths are very long and ugly in code. I have used type abbreviations to alleviate this, but obviously this is a manual process. The F# open keyword does not support this. Is there another way? Update: as pointed out in the answer and comments this is wrong. You can open a type provided namespace. I had not realised I was looking at deeply nested types, not a namespace.
This is tricky - parameterized type providers (like the standard SQL providers or the F# Data providers for XML and JSON) need to put all types that they generate (representing tables, XML nodes, etc) inside the main generated type. So all types that you might want to use are hidden somewhere as nested types of the main type (with parameters specified).
This makes sense - if you use the type provider with multiple parameters, the types generated for each configuration have to be separate.
As #kvb points out, you cannot open a nested type, but you can use type aliases to make this a bit less painful. For example, using F# Data, I can define an alias R that lets me access all the generated domain types with just two additional characters:
#r #"..\packages\FSharp.Data.1.1.10\lib\net40\FSharp.Data.dll"
open FSharp.Data
type RssFeed = XmlProvider<"http://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml">
type R = RssFeed.DomainTypes
let printTitle (itm:R.Item) = printfn "%A" itm.Title

How do I create an F# Type Provider for a generated assembly?

I'm having problems using any types created in an assembly for an F# Generative Type Provider. I created a YouTube video that demonstrates this.
The error messages I get are:
The module/namespace 'tutorial' from compilation unit 'Addressbook1' did not contain the namespace, module or type 'Person'
A reference to the type 'tutorial.Person' in assembly 'Addressbook1' was found, but the type could not be found in that assembly
I don't understand because the type is definitely in the assembly. For troubleshooting this, the assembly is a very basic C# dll. The code in the video is available via git:
git url: https://code.google.com/p/froto/
git branch: help
Any troubleshooting ideas would be appreciated. I'm hoping to make more progress on an F# Type Provider for .proto files, but I'm stuck on this.
I've taken a quick look at your code - as I mentioned in a comment I think you would be much better served by using the ProvidedTypes API that is defined by the F# 3.0 Sample Pack and documented (a bit) on MSDN.
Basically, the raw type provider API has a lot of assumptions baked in which will be hard for you to maintain by hand. I think that the specific problem you have is that the compiler expects to see a type named tutorial.Person in your assembly (since it's the return type of a method on tutorial.AddressbookProto, which you are exposing as a generated type), but it isn't ever embedded into your assembly.
However, this is really only one of several problems - as you've probably realized, your will see additional errors if the type that you're defining is called anything other than tutorial.AddressbookProto. That's because you're using a concrete type as the return from ApplyStaticArguments, but you would typically want to use a synthetic System.Type instance that accurately reflects the namespace and type name that the user used (e.g. in the ProvidedTypes API the ProvidedTypeDefinition class inherits from System.Type and handles this bookkeeping).

Do F# 3.0 type providers use the DLR under the hood?

Do F# type providers work by using the DLR under the hood? That is to say, do they work in the way that the dynamic keyword in C# does? How is this related to expando objects?
How does codegen fit in?
Type providers are plugin to the compilation process. Internally a type provider may use DLR or anything but when the compiler ask it for a type it needs to return a type that is statically resolved at compile time. Think of it like rather than a human creating a type (class in C#) you have a assembly (type provider) which the compiler can ask to create a new type at compile time.
Ex: In case of SQL type provider the type representing the tables will be generated at compile time and put in the assembly as static types.
Type providers solve similar problem as the dynamic keyword in C# - both of them were designed to make it easier to access data that have some structure that is not described in your programming langauge and so you need to somehow infer it later.
The dynamic keyword just lets you access any member (i.e. data filed) or method at compile time and then decides how to handle the operation at runtime. If you're using it to access .NET object, then it will use DLR, but if you're accessing some other object (like JSON data) then it will perform some simple dictionary lookup.
F# type providers are quite different - they infer the structure at compile time and pass it to the F# compiler. The compiler will then check all your code. The type provider also decides how the access to a field or method should be compiled. Typically, it will either replace it with an ordinary .NET type (so it will be compiled as normal .NET invocation) or it will replace the object with some dictionary lookup. A type provider may use DLR under the cover, but I don't think it is very common case.

Mapping constructor arguments to settings in the app.config

With StructureMap, I know that you can wire constructor arguments to app settings when mapping in code, and you can specify constructor arguments when defining the DefaultInstance in the XML config, but is there a way to have the XML configuration look at its own app.config settings?
My specific case was using Entity, so maybe this isn't applicable for everything, but rather than duplicating the same connection string information, you can use "Name=MyConnectionString" as a connection string and the framework will automatically pull the named connection string from the app.config/web.config. This does what I need it to.

Best way to use an IoC container for retrieving runtime settings

I have an C# dll project for which I have to store the runtime settings in an external XML file, and this dll will be used in an ASP.NET/ASP.NET MVC application for which I also have to store the runtime settings in a external file.
Which IoC container can be used to create an object with the runtime settings loaded from a specific external file (or app.config/web.config), and also works for web applications running in medium trust? Any howto/tutorial would be greatly appreciated.
So far I've found only this articles:
Use Castle Windsor to Read Your Config Files Automatically
Getting rid of strings (3): take your app settings to the next level
Update
I'm sending mails from my dll to a variable number of SMTP servers, based on the current record type. For type A I'm using a given SMTP server+port, for type B I'm using an alternate set of server+port values. Of course, I want to be able to modify those values after deployment, so I store them in a XML file.
If I'm storing the SMTP settings as a SMTPConfiguration class with 2 properties (SMTPServer as String and SMTPPort as Int32), is it possible to return from an IoC container the required object based on the given record type, and what is the best way to read the runtime settings in order to build the returning object?
Update2
Let's say I'm storing in the configuration file the following parameters: ASMTPServer, BSMTPServer, ASMTPPort, BSMTPPort.
I can use Castle DictionaryAdapter to read all those settings as properties of an AppConfiguration class.
What is the recommended method to specify that the required SMTPConfiguration class should use ASMTPServer and ASMTPPort values if I'm using a type A record as a parameter (and should use BSMTPServer and BSMTPPort values if I'm using a type B record as a parameter) ? Also, how can I specify that the AppConfiguration is required in this process?
Is there a pattern for initializing objects created wth a DI container
Windsor Config Parameters With Non-Primitive Types

Resources