Type Providers - Could I generate a type at compilation-time that decorates all methods of a type somehow? - f#

I've read about the great capabilities of Type Providers, such as static-typing when querying JSON documents, so I can imagine that I can create what I have in my mind at the moment, with this technology.
Let's say I want to allow a consumer of my TypeProvider-library Foo a way to create a type Bar, which will have the following pre-condition for each of their methods: check the mutable state of a boolean disposed field, if it's true, throw an ObjectDisposedException.
Would this be possible? How could one define such an implementation of this high-level type creator?

A couple of years back Keith Battocchi published a project called ILBuilder. Among other things ILBuilder contains a method type provider in ILBuilder.fs that provides methods for types in mscorlib, e.g.
MethodProvider.Methods.System.Console.``WriteLine : string*obj->unit`
It is possible you could use this as a starting point for a type provider that wraps classes from another assembly and provides methods.
Another option might be to consider Ross McKinlay's Mixin Type Provider that (ab)uses F#'s Type Provider mechanism to provide meta-programming capabilities.
Yet another option might be to use PostSharp, Fody etc. to do IL weaving, or code generation via reflection to build proxy classes.
That said probably the lowest friction solution would be to create a function that checks for disposal and manually add it to each member.

Related

In Spring4D is it possible to register generic interfaces?

I have classes that have a constructor such as
constructor Create(Factory: IFactory<IConnection>)
When I try and register the IFactory in the container
Container.RegisterType<IFactory<IConnection>,TConnectionFactory>
or
Container.RegisterType<TConnectionFactory>.Implements<IFactory<IConnection>>
I get an error stating that the interface does not have a guid.
I don't really want to add lots of pointless interfaces such as
IConnectionFactory = interface(IFactory<IConnection>)
['{45106BA8-43E7-4D26-B0EF-1639871B93E4}']
end;
to get around this but is this the only way?
Many thanks
As you found out the generic interface can have a GUID.
That itself causes no harm until you QueryInterface/Supports IList<string> from something that is an IList<Integer> which would erroneously succeed and subsequently fail once you start working with it. FWIW since you mentioned those types while the collection interfaces all have guids there is no need to ever do such querying when using them but they are required internally which then stays within the same generic type argument.
Currently the GUID is being used to check and get the interface from the implementing object because the RTL only supports doing that with a GUID and not with typeinfo.
In fact following code would not raise an exception during the registration but eventually cause defects when being resolved:
RegisterType<IFactory<IConnection>, TSomeFactory> where TSomeFactory implements IFactory<ISomethingElse>
However there is some rather hidden typeinfo available (see the commented line in System.TInterfaceTable) that has the exact typeinfo of the implemented interfaces. Spring4D internally uses that at some places, for example Spring.Reflection.TRttiTypeHelper.GetInterfaces.
That could be used but then there is another catch: generic types across multiple modules have different typeinfo. So it's not so easy to simply use that information to validate during registration and query the interface from the implementing class because right now the container (via some extension) supports registrations and dependencies across multiple modules.
Making the registration more robust and if possible remove the requirement for having a GUID on the interface is something I have on my list for the container refactoring which is planned for later this year.

Typhoon: Injecting run-time arguments into a singleton

I'm trying to figure out how to inject run-time arguments into a singleton when it is created, and then have those arguments just be remembered from then on. I'm not sure if the interface for run-time arguments can support this, though. Say, for example, I have a Client object that requires a token, and has the following initializer:
+ (instancetype)initWithToken:(NSString *)token;
The token is obtained at runtime from the server and is different for every user, so I can't simply put the NSString in the definition. So I create the following method on my Typhoon assembly:
- (Client *)clientWithToken:(NSString *)token;
However, in the future (when I'm injecting this client into other classes), I won't have the token on hand to call this method with. So I would like to just be able to inject [self client], for example. Since the client is a singleton and has already been created, the token isn't necessary, anyway.
However, I can't seem to find a way to do this. Obviously, defining a separate method called client would just return a different client. Can I just call clientWithToken:nil and the argument will be ignored if the client already exists? Perhaps traversing the assembly's singletons array would work, but that is obviously very inelegant.
I have considered injecting by type (so I don't need a method to call), but I have multiple different clients of the same type, so I need to be explicit about which client to inject. Of course, there is also the option of removing this parameter from the initializer, and instead setting it as a property from outside the assembly; however this pattern is used throughout our application, so I would like to avoid rewriting that much code.
Thank you.
Reviewing the Typhoon User Guide's 'When to Use Runtime Arguments' shows that this scenario isn't really a good match. Runtime arguments are great when we have a top-level component that mixes some static dependencies with information that is known later - thus avoiding the creation of a custom 'factory' class. Its not possible to use them in the way described.
Instead consider the following suggestions:
Inject a shared context class
Create a mutable Session model object and register it with Typhoon. Update the state on this model when you have a token. Inject this into the clients, which will use this session information when making connections.
Aspect Hook
Hook your clients so that before a method is invoked the token information is available. This could be done by:
Using an Aspects library like this one.
Define a Protocol for the clients and wrap the base implementation in one that is security aware.

protected virtual methods in f#

F# does not support the definition of protected methods. Here it is explained why
F# replaces virtualmethods with abstractmethods defined in abstract classes (see here).
I was wondering if there is a way to prevent access to abstract methods from outside the derived classes at all.
Like Patryk Ćwiek, I also don't think it's possible, but here's one alternative:
From Design Patterns we know that we should favour Composition over Inheritance. In my experience, everything you can do with Inheritance, you can also do with Composition. As an example, you can always replace Template Method with a Strategy.
A Template Method is a typical use of an abstract method, but if you replace it with a Strategy, you can (sort of) hide it from clients:
type Foo(strategy : IBar) =
member this.CreateStuff() =
// 1. Do something concrete here
// 2. Use strategy for something here
// 3. Do something else concrete here
// 4. Return a result
No outside client of Foo can invoke strategy, so that accomplishes the same goal as making a member protected.
You may argue that the original creator of Foo may keep a reference to strategy, and will still be able to invoke it. That's true, but protected members aren't really completely hidden either, because you can often derive from the class in question, which enables you to invoke the protected member.
Another point is that if you separate the creator of Foo from the client of Foo, the strategy will be unavailable to the client.

How do you inject your dependencies when they need differents parameters?

For instance I have this bit of code
public class ProductService{
private IProductDataSource _dataSource = DependencyManager.Get<IProductDataSource>();
public Product Get(int id){
return _dataSource.Select(id);
}
}
I have 2 different data source:
XML file which contains the informations only in 1 language,
a SQL data base which contains the informations in many languages.
So I created 2 implementation for IProductDataSource, for for each kind of datasource.
But how do I send the required language to the SQL data source ?
I add the parameter "language" to the method "IProductDataSource.Select" even if I won't use it in the case of the XML implementation.
Inside the SQL implementation I get the language from a global state ?
I add the language to the constructor of my SQL implementation, but then I won't use my DependencyManager and handle my self the dependency injection.
Maybe my first solution is not good.
The third option is the way to go. Inject the language configuration to your SQL implementation. Also get rid of your DependencyManager ServiceLocator and use constructor injection instead.
If your application needs to work with multiple languages in a single instance I think point one is a sensible approach. If the underlying data does not provide translations for a request language then return null. There is another solution in this scenario. I'm assuming that what you have is a list of products and language translations for each product. Can you refactor your model so that you do not need to specify or asertain the langauge until you reference language specific text? The point being a product is a product regardless of the language you choose to describe it. i.e. one product instance per product, only the product id on the Datasource.Select(..) method and some other abstraction mechanism to deal with accessing the correct text translation.
If however each instance of your application is only concerned with one language set I second Mr Gloor.
First of all I need to point out that you are NOT injecting any dependencies with your example - you are depending on a service locator (DependencyManager) to get them for you. Dependency injection, simply put, is when your classes are unaware of who provides the dependencies, e.g. using a constructor, a setter, a method. As it was already mentioned in the other answers, Service locator is an anti-pattern and should be avoided. The reasons are described in this great article.
Another thing is that the settings you are mentioning, such as language or currency, seem to be localization related and would probably be better dealt with using the built-in mechanisms of your language of choice (e.g. resource files, etc).
Now, having said that, depending on how the rest of your code is structured you have several options to solve this while still using Service locator:
You could have SqlDataSource depend on some ILanguageProvider which pulls the current language from somewhere. However, with more settings like these (or if it is difficult to get current language in an isolated way) this can get messy very fast.
You could depend on IProductDataSourceFactory instead (or, if you are using C#, Func<IProductDataSource>) which would return the concrete implementation with the correct settings. Again, you need to be able to get the current language in an isolated way in order to use this.
You could go with option 1 in your question. This would be a leaky abstraction but would be the simplest to implement.
However, if you decide to get rid of service locator and start using some DI container, the best solution would be using option 3 (as it was already stated) and configuring container accordingly to provide the correct value. Some good ideas of how to do this in an elegant way can be found in the answer to this question

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.

Resources