I want to let Ninject resolve an instance of T based on a specific enum input value.
I have read about Ninject's factory extension, but I couldn't find any example having the factory resolve a specific class based on an enum.
Each class derives from a base class and that derived class has several, different interfaces that Ninject also has to resolve.
For example this is how the interface should look like:
public interface IProcessFactory
{
T Create<T>(ProcessIndex processIndex) where T : BaseProcess;
}
How can this be achieved ?
This is not supported out of the box. You can customize it by writing your own implementation of IInstanceProvider(also see ninject Wiki entry. Then configure it for your specific factory:
kernel.Bind<IFooFactory>()
.ToFactory(() => new MyCustomInstanceProvider());
Or alternatively, if you want to change the behavior of all .ToFactory() bindings: Rebind IInstanceProvider after loading Ninject.Extensions.Factory:
kernel.Rebind<IInstanceProvider>().To<MyCustomInstanceProvider>();
However, if it's not something you need often i would consider manually writing a factory implementation # composition root.
Anyway, in both cases you'll need to know how to create a conditional binding. Ninject calls it Contextual Binding.
One method is to use Binding-Metadata:
const string EnumKey = "EnumKey";
Bind<IFoo>().To<AFoo>()
.WithMetadata(EnumKey, MyEnum.A);
IResolutionRoot.Get<IFoo>(x => x.Get<MyEnum>(EnumKey) == MyEnum.A);
Another way would be to create a custom IParameter and use in a conditional binding:
Bind<IFoo>().To<AFoo>()
.When(x => x.Parameters.OfType<MyParameter>().Single().Value == A);
There are several options available to implement AbstractFactory using DI (Ninject).
After analyzing the options, I came up with the solution provided by Mark Seemann, see http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/
The Container Based Factory solution is the one I chose, because:
Performance: on demand DI resolve on request, no instances loaded in the constructor
Easy for refactor: when we want to replace the current DI framework (Ninject) to a much better performer with (almost or even better) featureset, the only place to change are the calls inside the factory and not in the NinjectModules/Composition Root.
See also at SO:
Simple Injector:Factory classes that need to create classes with dependencies
Related
I have parts of my code which depend on more than one implementation of the same interface, and other parts which depend on one of the implementations.
I am registering implementations like:
services.AddSingleton<MyInterface, FirstImplementation>();
services.AddSingleton<MyInterface, SecondImplementation>();
Then getting both implementations when needed like:
var implementations= serviceProvider.GetServices<MyInterface>();
My Issue is when I need one of them, I am trying the following which returns null:
var firstImplementation= serviceProvider.GetService<FirstImplementation>();
Of course I could use:
var implementations= serviceProvider.GetServices<MyInterface>();
foreach (var implementation in implementations)
{
if (typeof(FirstImplementation) == implementation.GetType())
{
FirstImplementation firstImplementation = (FirstImplementation)implementation;
}
}
But I am thinking that I can get my FirstImplementation directly somehow.
The container knows how to resolve a FirstImplementation when asked for the MyInterface, how ever is was not told how to resolve a FirstImplementation when asked specifically for a FirstImplementation.
The built-in services container is meant to serve the basic needs of the framework and most consumer applications built on it. It is bare bones and needs to be configured explicitly to behave as desired. You will need to also tell it how to get the implementations when explicitly asked for the implementations
//register implementations first
services.AddSingleton<FirstImplementation>();
services.AddSingleton<SecondImplementation>();
//register interfaces using factory that return implementation singleton
services.AddSingleton<MyInterface, FirstImplementation>(p => p.GetService<FirstImplementation>());
services.AddSingleton<MyInterface, SecondImplementation>(p => p.GetService<SecondImplementation>());
So now you can get your FirstImplementation directly and get the same instance
var firstImplementation = serviceProvider.GetService<FirstImplementation>();
Actually what you did is not a good practice, You can create two different interfaces inherited from your base interface (MyInterface) and then register each implementation corresponding on the proper interface, After that in the part of your code which you need specific implementation you can ask from IoC go give you back specific implementation of your significant interface:
Implementation
public interface IFirstImplementation:MyInterface {}
public interface ISecondImplementation:MyInterface {}
Registeration
services.AddTransient<IFirstImplementation, FirstImplementation>();
services.AddTransient<ISecondImplementation, SecondImplementation>();
Usage
var firstImplementation= serviceProvider.GetService<IFirstImplementation>();
Microsoft.Extensions.Dependencyinjection provides the basic needs of Dependency injection, and there's other IoC container framework available for .NET which can solve your problem. For example, you can use Autofac's Named Services like below:
//registration method
var builder = new ContainerBuilder();
...
builder.RegisterType<FirstImplementation>().Named<MyInterface>("first");
builder.RegisterType<SecondImplementation>().Named<MyInterface>("second");
//resolve method
var firstImplementation = container.ResolveNamed<MyInterface>("first");
For more complicated scenario, you can use Keyed Services which supports resolving with an Index and attributes.
You also need to pay attention to the instance scope if uses Autofac.
in a WPF application I'm using Caliburn Micro for MVVM pattern... I want to try another IoC and want to reuse the most of the existing code...
In my application I've defined all the exportable class via attribute as
[Export(typeof(ITaggable))]
[Export(typeof(CorporateActionViewModel))]
[Export(typeof(IScreen))]
public class CorporateActionViewModel :...
How can I register them without doing manually
ContainerInstance.Register<ITaggable, CorporateActionViewModel>();
ContainerInstance.Register<IScreen, CorporateActionViewModel>();
ContainerInstance.Register<CorporateActionViewModel, CorporateActionViewModel>();
Another question is regarding the Lazy initialization... I've read here how to register lazy... but do I have to call the Container.Verify() or not?
Thanks
The use of the ExportAttribute thoughout your complete source just to register all your types sounds like a violation of the Dependency Inversion Principle. Which is on its own questionable but it has several disadvantages for sure.
Simple Injector has no need for using attributes to find the classes you want to register. It is actually one of the design principles
of the Simple Injector crew.
You could easily (well easy... depending on your current design offcourse...) remove the attribute if you follow the SOLID principles for your viewmodels (and corresponding views).
If we take a typical LoB application where we have a bunch of entities in a database we could split our viewmodel/view design in these generic interfaces which your viewmodels will implement (one at a time offcourse):
//for a typical datagrid view of your entities with e.g. Add, Edit and Delete button
IWorkspace<TEntity>;
//for a typical edit view for one entity (including possible child entities)
IEditEntity<TEntity>;
//for choosing a specific foreign entity type from your edit view
//e.g. your editing an order and need to specify the customer
IChooseEntity<TEntity>
Using these we will get very specific viewmodels which are SOLID and which still could be composed to a very big complicated view for the user if you wish.
You could register these types very easily with Simple Injector using a batch registration like this:
container.RegisterManyForOpenGeneric(
typeof(IChooseEntityViewModel<>), Assembly.GetExecutingAssembly());
As a bonus of this design you could wrap your viewmodels with one or more decorators which could be used to some real MVVM stuff like find your view, bind it to the viewmodel and show the view in window/page etc.
If you want to read more about decorators, in combination with simple injector you can find some nice articles here (don't forget the various links).
This query will find all types marked with ExportAttribute
private IEnumerable<Type> GetExportedTypes()
{
return from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where Attribute.IsDefined(type, typeof(ExportAttribute))
select type;
}
And this query will find all the services published for a type using ExportAttribute
private IEnumerable<Type> GetServicesFromType(Type type)
{
return from attribute in Attribute
.GetCustomAttributes(type, typeof(ExportAttribute))
select ((ExportAttribute)attribute).ContractType;
}
These queries can be used something like this
var container = new Container();
foreach(var type in GetExportedTypes())
{
foreach (var service in GetServicesFromType(type))
{
container.Register(service, type);
}
}
container.Verify();
As for your question regarding Verify()? It is never mandatory to call Verify but it is always advised. The Diagnostic Services are there to help.
If you explicitly register both the lazy and the normal version of a registration, your object graph will still be fully verifiable. Take a look at this registration:
container.Register<ITaggable, CorporateActionViewModel>();
container.Register<Lazy<ITaggable>>(
() => new Lazy<ITaggable>(container.GetInstance<ITaggable>));
container.Verify();
Verify will walk through all explicit registrations and tries to create an instance for each of the registrations. This means that it will create a Lazy<ITaggable> instance. Of course being able to create an Lazy<ITaggable> doesn't mean that the CorporateActionViewModel can be created, but Simple Injector will also verify the ITaggable registration. Those two together make sure that your complete DI configuration is verifiable.
The following configuration however will give you a false sense of security:
container.Register<Lazy<ITaggable>>(
() => new Lazy<ITaggable>(container.GetInstance<CorporateActionViewModel>));
container.Verify();
Here the Lazy<ITaggable> registration uses the GetInstance<CorporateActionViewModel> as factory method, but CorporateActionViewModel is not registered explicitly. During verification, Simple Injector will create the Lazy<ITaggable> which will obviously succeed, but it will not automatically call the Lazy<T>.Value property for you (which is deliberate, because there might be a reason why you postponed the creation of the object graph).
But please reconsider your strategy of injecting Lazy throughout your code base. This is a bad idea and bad practice. Please read this and this for more information.
And in answer to your second question. (Did you know you could edit your original question. This keeps things understandable)
I think I can refactor it to
ContainerInstance.RegisterSingle<ISharedModuleObject>(
new SharedModuleObject { DataLavorativa = DateTime.Today,
DataLavorativaPrecedente = DateTime.Today });
But is this ok?
I do not think so. Your calling it a factory, so RegisterSingle(), which registers a singleton instance is not ok.
I think your implementation should be:
public class SharedModuleObject : ISharedModuleObject
{
public SharedModuleObject()
{
this.DataLavorativa = DateTime.Now;
this.DataLavorativaPrecedente = DateTime.Now;
}
public DateTime DataLavorativaPrecedente { get; set; }
public DateTime DataLavorativa { get; set; }
}
and register it like:
ContainerInstance.Register<ISharedModuleObject, SharedModuleObject>();
This will register a transient instance of the SharedModuleObject. So you get a new instance every time it resolved from the container.
Edit:
From your comment I understand you actually need a singleton. In that case your code was ok, but this seems to be a little cleaner to me:
ContainerInstance.RegisterSingle<ISharedModuleObject, SharedModuleObject>();
Let's suppose I have two different concrete classes that both implement the same interface:
public interface IDataSource{
Connection CreateConnection();
}
public class DataSourceA: IDataSource
{
....
}
public class DataSourceB: IDataSource
{
....
}
Now I want to register both of these with my unity container:
var container = new UnityContainer();
container.RegisterType<IDataSource, DataSourceA>("A");
container.RegisterType<IDataSource, DataSourceB>("B");
I know that I can specify the mapping name when I resolve a dependency :
var myDataSource = conatiner.Resolve<IDataSource>("A");
However, in my case, I won't be resolving the dependency myself. I am creating many different controllers and I will be using UnityDependencyResolver (from ASP.Net MCVC) to create all the controllers. Some of my controllers required DataSource A, some require DataSource B, and some require both. What I'd like to do is specify which one to use as an attribute on the constructor parameter, like this:
public class ReportController{
public ReportController([InjectionQualifier("A")] IDataSource dataSource)
{
...
}
}
Is something like that possible? I come from the spring world in java and I would use an #Qualifier annotation in this case using that stack.
The attribute you are looking for is
[Dependency("A")]
With Unity how do I inject a named dependency into a constructor?
I personally don't like using the Dependency Attribute because you're directly depending on the Unity library. You might as well pass in the IUnityContainer in your constructor.
Usually when you need to use named dependencies, it's because you are trying to implement some kind of strategy pattern.
What I do is that I isolate Unity in a class called StrategyResolver and inject the StrategyResolver as dependency. Since the StrategyResolver belongs to me then my "services" classes no longer have any hard dependencies on any Unity library objects except inside the StrategyResolver but that's acceptable since I will never have to modify the StrategyResolver ever again when adding new strategies in the future.
Take a look, I've detailed my approach in this answer with code examples : https://stackoverflow.com/a/37882179/483638
I have run into a scenario that I would like to solve with Ninject but up until this point none of my work with it has cross this type of situation.
WCF Service App
W3C Log Parsing App (overly simplistic for demonstration purposes).
IW3CLogItem implemented by W3CLogItem
W3CLogItem has a public member of type IUrlData (contains the important data but can be one of 5 concrete implementations depending on what it contains).
The decision of which concrete implementation to use is based off of a string match and its constructor takes a regex pattern it will use to parse the data as well as the string to be parsed.
Currently I have a simple factory that does the string comparisons and then calls Create() to return a new concrete object (DocumentUrlItem, DriverUrlItem, AssetUrlItem, etc...).
I was looking at the wiki docs and how to name a binding, but even that only gets me half of the way.
The question I have is: Can this be done without a factory? Can I somehow place a conditional attribute on a binding (i.e. .contains, etc...) that evaluates to true to know which binding to use or am I better off sticking with the factory?
Let elaborate a bit.
If I were to write the factory without ninject in a simplified way, it would look like this:
protected IUrlData Create(string urldata)
{
if (urldata.Contains("bob"))
{
return new BobUrlData(urldata)
}
else if (urldata.Contains("tim"))
{
return new TimUrlData(urldata);
}
}
A couple of things of note:
1) The number of classes that implement IUrlData will grow over time. The strings "tim", and "bob" will be coming from a database.
2) The urldata being passed into BobUrlData and TimUrlData is not the only parameter in the real world, there will also be a regular expression (also sourced from the database which is calculated by the entries timestamp that knows how to handle that particular entry as they have evolved over time.
3) I am really curious if this can be accomplished with Ninject without the need for the factory all together, to somehow through metadata or names achieve the same work but all through bindings all while leaving the code extensible but read-only (other than the binding modules).
You are able to bind to methods with Ninject.
Ninject Wiki - Contextual Binding
You shouldn't need the factory anymore if you set up the method to return what you need. I can't say one is better than the other though since they both work, but I do prefer the factory doing the work and having that access Ninject to give me the correct implementation. Your result is still the same in the end.
Also, right above on the same page is Specifying Constraints.
from a purist point of view, an abstract factory is the correct way to abstract out the implementation from the interface of an object. with that said, ninject offers various ways of implementing what you want without using an abstract factory. The ones that I feel will help you most are ToMethod and providers
I'm working on a module that requires a strictly decoupled interface. Specifically, after instantiating the root object (a datasource), the user's only supposed to interact with the object model via interfaces. I have actual factory objects (I'm calling them providers) to supply instances that implement these interfaces, but that left the clumsiness of getting the providers. To do so, I've supplied a couple methods on the datasource:
public class MyDataSource
{
private Dictionary<Type, Type> providerInterfaceMapping = new Dictionary<Type, Type>()
{
{ typeof(IFooProvider), typeof(FooProvider) },
{ typeof(IBarProvider), typeof(BarProvider) },
// And so forth
};
public TProviderInterface GetProvider<TProviderInterface>()
{
try
{
Type impl = providerInterfaceMapping[typeof(TProviderInterface)];
var inst = Activator.CreateInstance(impl);
return (TProviderInterface)inst;
}
catch(KeyNotFoundException ex)
{
throw new NotSupportedException("The requested interface could not be provided.", ex);
}
}
}
I've modified some details on the fly to simplify (e.g., this code snippet doesn't include the parameters passed to the implementation instance that's created). Is this a good general approach for implementation of a factory method in C#?
You should rather take a step back and ask whether using a factory method at all is a good idea? In my opinion, it is not.
There are more than one issue with factory methods, and your example illustrates several:
You need to have a hard reference to the implementation (FooProvider in addition to IFooProvider), which is exactly the situation you are trying to avoid in the first place. Even if the rest of your code only consumes IFooProvider, your library is still tightly coupled to FooProvider. Some other developer may come by and start using FooProvider directly if he/she isn't aware of your factory method.
You only support implementations that have default constructors, since you are using Activator.CreateInstance. This prevents you from using nested dependencies.
Instead of trying to manually control dependencies, I would recommend that you take a look at Dependency Injection (DI). Whenever your code needs an IFooProvider, supply it with Constructor Injection.
Don't reinvent your own implementation of dependency injection, use an existing library like Spring.NET or the Microsoft Unity application block.
Injecting dependencies is a common programming problem that you shouldn't have to solve yourself. There are some nice lightweight libraries out there (I mentioned a couple above) that do the job well. They support both declarative and imperative models of defining dependencies and are quite good at what they do.
Technically this is fine, however most times when I see a factory it usually returns the same type interface, for instance something like IProvider rather than IFooProvider or IBarProvider which to me doesn't make sense. If you are going to have FooProvider and BarProvider then why have different interfaces for them. I would use one interface IProvider and have FooProvider and BarProvider implement that.
Regardless of the rightness or wrongness of using the factory method (as that is not what you asked about!), your implementation looks fine to me.
Something that may work for you better than hardcoding the type mapping is putting that info in a configuration file and loading it in your app.
For what it is worth I use this pattern all the time and have abstracted some of this sort of logic into a reusable assembly. It uses reflection, generics and attributes to locate and bind the concrete types at runtime. http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx
This helps to address Mark's concern because implementation types are not hardcoded, and further the implementation types are determined by the installation, not in project assembly references.