I am using dependency resolver and i have added my unity container to the same. So by default "GoldCustomer" gets injected in to the "CustomerController" as per the current container rules.
IUnityContainer oContainer = new UnityContainer();
oContainer.RegisterType<ICustomer, GoldCustomer>(); // injects GoldCustomer
DependencyResolver.SetResolver(new UnityDependencyResolver(oContainer));
If i want to change by current container configuration i can always create new Container and set it and call the SetResolver again. I know that the above code should be configurable via XML config but still if we need to pickup new container objects we have to still call the setresolver.
Is this the right way or are there better ways of changing container depedency rules while the application running.
Second what are the events where we can change the container is it session_start , httphandler's or something better.
Firstly why would you need multiple containers? It must be the singleton object who keeps all the dependency registered since the application started.
In a practice I would say keep single container and if required create multiple Registration function in separate assemblies and invoke all of them in a AppBootstrapper.
If it's an application then best way is to use the Application start with Async behaviour so that the startup doesn't get affected.
======================================================
Unfortunately the Named registration is the only option and Unity required to register with names explicitly. Thats why I personally like DI containers like Autofac and SimpleInjector. They are fast and They allow multiple registrations of an Interface with multiple Types and the resolver uses Type resolver and Named resolver methods without explicitly asking for Names and those resolvers are overridable too.
I am not sure why it does not look that complex to me , If I understand question quickly I can do it as follows,
assume that I have interface IMovieRepository and two classes implementing it EnglishMovieRepository and HindiMovieRepository.
How about resolving them as in UnityConfig.cs as follows,
If(condition)
{
container.RegisterType<IMovieRepository, EnglishMovieRepository>();
}
else
{
container.RegisterType<IMovieRepository, HindiMovieRepository>();
}
If requirement is something different then please let me know
Thanks
/dj
Related
We have a large monolithic legacy application with around 45 projects with several different composition roots (console, web, api apps). Most component registration is done in the composition roots of the apps and many WindsorInstallers. We want to remove component registration from the composition roots and into WindsorInstallers for each project in the solution so we no longer need to modify the composition roots when we add a new project, each project should be responsible for its own component registration. We are looking to incrementally make this change to our code base because I tried just having Castle Windsor scan all of our assemblies and run all of our Installers, but that caused a myriad of issues that will need to be looked into over time.
With all of that said, we are looking for a way to only run certain installers, so we can go back a fix the broken ones over time, but all new ones will automatically be used. Below is the approach I was headed towards, but cannot figure out or do not even know if it is possible.
All composition roots would have something like this so that all Installers are always ran.
container.Install(
FromAssembly.InDirectory(new AssemblyFilter(HttpRuntime.BinDirectory))
);
However I would like this install code to only run Installers of type IAutoInstaller. In this way I could go back and fix my legacy installers just by changing the interface to IAutoInstaller and then would never need to modify the composition roots.
public interface IAutoInstaller : IWindsorInstaller
{
}
public class ScheduledPaymentInstaller : IAutoInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromAssemblyNamed("DryFly.ScheduledPayments")
.Pick()
.WithServiceDefaultInterfaces().LifestylePerWebRequest());
}
}
In summary what I am after is a way to auto execute certain installers from the composition root so that when I add new projects I do not need to modify that code. I would just need to add a new Installer to the new project. Is there a different approach to solve this problem or can this be done via Castle Windsor?
It is possible, but not pretty:
var container = new WindsorContainer();
var installers = AppDomain.CurrentDomain
.GetAssemblies() // Load all assemblies in the current application domain
.SelectMany(s => s.GetTypes()) // project all types contained in all assemblies into a single collection
.Where(type => typeof(IAutoInstaller).IsAssignableFrom(type) && type.IsClass) // find all types that implement IAutoInstaller and are classes (this filters out the interface itself)
.Select(Activator.CreateInstance) // project all types into instances - this relies on all of them containing a parameterless constructor
.Cast<IAutoInstaller>(); // project the Ienumerable<object> into an Ienumerable<IAutoInstaller>
foreach (var installer in installers)
{
installer.Install(container, container.Kernel.ConfigurationStore);
}
There is a massive caveat here, which is that your installers must have a parameterless constructor for this to work. If for some reason this isn't the case, your problem becomes a lot harder to solve generically.
Unfortunately, the IWindsorInstaller interface only enforces a method expecting the container itself, and an implementation of IConfigurationStore. So even if you're not using a configuration store, you still have to supply it. Luckily, when you instantiate a WindsorContainer using the default constructor, it wires up a default Kernel with a DefaultConfigurationStore implementation. This allows you to just pass that in.
If, however, you are using a custom Configuration Store (such as when using an XML configuration interpreter), and this configuration store is owned by another container, or a parent or child container related to your current container, and you require access to the values of that particular store in your particular installer, you'll have to pass that particular store reference into the installer.
As you can see from the list of caveats around the store, you are probably safe to just pass in the kernel default, or even new up a DefaultConfigurationStore.
I'm a relatively new user of both Autofac and ASP.NET Core. I've recently ported a small project from a 'classic' ASP.NET WebAPI project to ASP.NET Core. I am having trouble with Autofac, specifically in registration of generic types.
This project uses a Command pattern, each command handler is a closed generic like
public class UpdateCustomerCommandHandler: ICommandHandler<UpdateCustomerCommand>
These command handlers are injected into the controllers like:
readonly private ICommandHandler<UpdateCustomerCommand> _updateCustomerCommand;
public ValuesController(ICommandHandler<UpdateCustomerCommand> updateCustomerCommand)
{
_updateCustomerCommand = updateCustomerCommand;
}
Autofac is configured (partially) as:
var builder = new ContainerBuilder();
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
//This doesn't seem to be working as expected.
builder.RegisterAssemblyTypes(assemblies)
.As(t => t.GetInterfaces()
.Where(a => a.IsClosedTypeOf(typeof(ICommandHandler<>)))
.Select(a => new KeyedService("commandHandler", a)));
The above does not seem to be registering the generic as expected. If I use the below method for registration, it works well.
builder.RegisterType<UpdateCustomerCommandHandler>().As<ICommandHandler<UpdateCustomerCommand>>();
When I say "It doesn't work", what I mean is that when attempting to instantiate the controller, I get "InvalidOperationException: Unable to resolve service for type 'BusinessLogic.ICommandHandler`1[BusinessLogic.UpdateCustomerCommand]' while attempting to activate 'AutoFac_Test.Controllers.ValuesController'."
This worked well in the Full WebAPI version of this project, but not after recreating it in ASP.NET Core. To be clear, this was working perfectly well before porting to ASP.NET Core.
Here is a link to the code that I've used to recreate this issue:
https://dl.dropboxusercontent.com/u/185950/AutoFac_Test.zip
**** EDIT AFTER SOLUTION DISCOVERED ****
There was nothing in fact wrong with my Autofac configuration and certainly not Autofac itself. What had happened was that I had renamed the output of my dependent assemblies in an effort to make the assembly scanning stuff (replacing of AppDomain.CurrentDomain.GetAssemblies() more elegant, however I never modified the dependencies of the API project to reference the new assemblies. So Autofac was scanning the correctly loaded assemblies which happened to be the older versions, which did not contain the interfaces and implementations I expected...
Autofac has built-in support to register closed types of open-generic.
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(ICommandHandler<>));
This will scan your assembly, find types that close the open generic ICommandHandler<> interface, and register each of them against the closed generic interface they implement - in your case, ICommandHandler<UpdateCustomerCommand>.
What doesn't work in your example is that you associate a key to your services. Autofac doesn't look for the keyed version of your ICommandHandler<UpdateCustomerCommand> when trying to instantiate the ValuesController, which is why you get the exception.
Edit after QuietSeditionist's comment:
I'll try to elaborate a bit on the keyed vs. default services. The way you registered your handlers is by associating the commandHandler key to them.
This means that once the container is built, here's the only way you can resolve such a handler:
// container will look for a registration for ICommandHandler<UpdateCustomerCommand> associated with the "commandHandler" key
container.ResolveKeyed<ICommandHandler<UpdateCustomerCommand>>("commandHandler");
When instantiating ValuesController, Autofac doesn't look for a keyed registration of ICommandHandler<UpdateCustomerCommand>, because it wasn't asked to.
The equivalent code it's executing is - and you can try to run that code yourself to get the exception:
// BOOM!
container.Resolve<ICommandHandler<UpdateCustomerCommand>>();
The reason your second registration works is because you didn't key the service:
// No key
builder
.RegisterType<UpdateCustomerCommandHandler>()
.As<ICommandHandler<UpdateCustomerCommand>>();
// commandHandler key
builder
.RegisterType<UpdateCustomerCommandHandler>()
.Keyed<ICommandHandler<UpdateCustomerCommand>>("commandHandler");
But since you don't want to register all your handlers one by one, here's how to register them without keying them:
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(ICommandHandler<>));
/Edit
I can see two scenarios where keying services can be useful:
You have several types implementing the same interface and you want to inject different implementations in different services. Let's say, you register both SqlConnection and DB2Connection as IDbConnection. You then have 2 services, one which is supposed to target SQL Server, the other one DB2. If they both depend on IDbConnection, you want to make sure you inject the correct one in each service.
If you use decorators, the way registrations work is you define the services to which the decorators will apply by a key - the first example is self-explanatory
Because Google brings you to this page even when you're trying to manually register types, I thought that even though this doesn't answer the asked question, it would be useful for future visitors. So, if you want to manually register a generic type, you would use this format:
service.AddTransient(typeof(IThing<>), typeof(GenericThing<>));
or if there's no interface, then just:
service.AddTransient(typeof(GenericThing<>));
and for completeness, if you have a generic with multiple types:
services.AddTransient(typeof(GenericThing<,>));
There's this software, X, which has this really complicated API that I have to write a facade for. I wrote a class library, XClientLibrary, and I made it using DI and IoC container (Unity). This was possible because my library exports services (interfaces) so users are not aware of the concrete classes which use constructor DI. They're also unaware of the IoC container.
The "root service" is a IXClient instance which is supposed to be created once and used as long as the application runs. (It is a desktop application btw). The X-client allows users to connect to X-hosts if they know the URL. A X-host allows users to access host's services and their services and so on (quite a complex object graph). This is sample user code:
// 1. app startup
XClientProvider provider = new XClientProvider(); // call only once per app
IXClient xClient = provider.GetClient(); // always returns the same instance
xClient.Startup();
// 2. app normal usage
IXHost host = xClient.ConnectToHost(new Uri("http://localhost")); // return new instance each time
IXService1 service = host.GetThis();
IXService2 otherService = service.DoThat();
...
host.Dispose();
// get another host, consume it, dispose it, etc
...
// 3. app shutdown
xClient.Shutdown();
provider.Dispose();
I tried to follow Mark Seemann's suggestions to implement this, but I'm not sure if they apply to a class library too. The client provider is the composition root, which is the only place where the IoC container is used. The composition root follows the RRR pattern:
the container is created on new XClientProvider() and configured
the container resolves IXClient when calling GetClient()
the container is disposed on provider.Dispose()
Things get complicated when the container is asked to resolve IXHost. Its implementation is:
internal class XHost : IXHost
public XHost(Uri uri, IXService1 service1)
The client is supposed to create XHost instances, so its implementation needs to know how to create IXService1:
internal class XClient : IXClient
public XClient(Func<IXService1> xService1DelegateFactory)
Invoking the delegate factory reaches the container which creates a IXService1. Also, let's say that in this graph there is a class XComponent7 which requires the exact IXService1 instance which was used to create the host:
internal class XComponent7 : IXService7
public XComponent7(Func<IXService1> service1DelegateFactory)
I have to use Func to deal with the circular dependency. The container should be configured such that once a IXService1 was resolved, it will provide the same instance whenever asked to resolve IXService1.
Now it gets really complicated. I want to restrict this behavior "per host resolve", meaning once a host is created the container should create a IXService1 and cache it and provide it to whatever component needs it, as long as the component is part of the object graph of the host. I also need a way to dispose all components when a host is disposed.
I was thinking I can do it using child containers. I can create one when users call ConnectToHost, ask it to resolve the host and dispose it on host disposal. The main container is still alive and won't be disposed until they call Dispose on the provider.
Problem is, I think it breaks the RRR pattern. So I wonder how RRR works when child container are involved... Maybe the IXHost is another "root" which can be directly resolved by the composition root? Or maybe there's a really smart Unity lifetime manager which can do what I need?
#Suiden So my understanding is: Your client is something that lets you lookup hosts (like a registry). Hosts offer services implemented by components. Every application has exactly one instance of your lookup/client. Your components not only implement services but might need other services to do their job. You want to resolve all parts of that object graph exactly once and when you dispose your client throw all of it away.
A couple of thoughts:
Circular references between dependencies (or services) is something you should try to avoid. If these services need each other that indicates they should be one service. That's what high cohesion, low coupling is about.
Unity does not clean up after itself. That means that even if you dispose a container that will not dispose the objects created by that container. The cleanup feature is on the wish list for Unity vNext
If you want to resolve an instance of some service and cache that instance inside your client/host wherever you should have a look at Lazy. It takes a Func to create an instance of T and evaluates that Func the first time the value is requested. So you can inject the Func into your classes or teach Unity to inject Lazy instances directly.
Child containers are a feature I find less than usefull. You can scope registration information and object lifetimes. But to make use of these scopes you would have to reference the appropriate child container. That means you are dropping dependency injection in favor of the ServiceLocator anti-pattern.
I have a base controller from which inherit all my controllers. This base controller has some properties I'd like to inject the using property injection.
My controller registration looks like this
builder.RegisterControllers(Assembly.GetExecutingAssembly()
I don't know how to access the base class and inject the properties.
This should work:
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
Some more info on the autofac website: http://code.google.com/p/autofac/wiki/PropertyInjection
You may want to consider using an Autofac Aggregate Service:
An aggregate service is useful when you need to treat a set of dependencies as one dependency. When a class depends on several constructor-injected services, or have several property-injected services, moving those services into a separate class yields a simpler API.
An example is super- and subclasses where the superclass have one or more constructor-injected dependencies. The subclasses must usually inherit these dependencies, even though they might only be useful to the superclass. With an aggregate service, the superclass constructor parameters can be collapsed into one parameter, reducing the repetitiveness in subclasses. Another important side effect is that subclasses are now insulated against changes in the superclass dependencies, introducing a new dependency in the superclass means only changing the aggregate service definition.
This works for me:
using Autofac;
using Autofac.Integration.Web;
using Autofac.Integration.Web.Mvc;
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();
nickvane's answer is correct. Just make sure
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
is after your all dependencies are registered. Or in other words, just right before you build your container.
So final code will look like
.
.
.
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
var container = builder.Build();
Need to call also for MVC:
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
For Web API:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
On this AutoFac "Best Practices" page (http://code.google.com/p/autofac/wiki/BestPractices), they say:
Don't Pass the Container Around
Giving components access to the container, or storing it in a public static property, or making functions like Resolve() available on a global 'IoC' class defeats the purpose of using dependency injection. Such designs have more in common with the Service Locator pattern.
If components have a dependency on the container, look at how they're using the container to retrieve services, and add those services to the component's (dependency injected) constructor arguments instead.
So what would be a better way to have one component "dynamically" instantiate another? Their second paragraph doesn't cover the case where the component that "may" need to be created will depend on the state of the system. Or when component A needs to create X number of component B.
To abstract away the instantiation of another component, you can use the Factory pattern:
public interface IComponentBFactory
{
IComponentB CreateComponentB();
}
public class ComponentA : IComponentA
{
private IComponentBFactory _componentBFactory;
public ComponentA(IComponentBFactory componentBFactory)
{
_componentBFactory = componentBFactory;
}
public void Foo()
{
var componentB = _componentBFactory.CreateComponentB();
...
}
}
Then the implementation can be registered with the IoC container.
A container is one way of assembling an object graph, but it certainly isn't the only way. It is an implementation detail. Keeping the objects free of this knowledge decouples them from infrastructure concerns. It also keeps them from having to know which version of a dependency to resolve.
Autofac actually has some special functionality for exactly this scenario - the details are on the wiki here: http://code.google.com/p/autofac/wiki/DelegateFactories.
In essence, if A needs to create multiple instances of B, A can take a dependency on Func<B> and Autofac will generate an implementation that returns new Bs out of the container.
The other suggestions above are of course valid - Autofac's approach has a couple of differences:
It avoids the need for a large number of factory interfaces
B (the product of the factory) can still have dependencies injected by the container
Hope this helps!
Nick
An IoC takes the responsibility for determining which version of a dependency a given object should use. This is useful for doing things like creating chains of objects that implement an interface as well as having a dependency on that interface (similar to a chain of command or decorator pattern).
By passing your container, you are putting the onus on the individual object to get the appropriate dependency, so it has to know how to. With typical IoC usage, the object only needs to declare that it has a dependency, not think about selecting between multiple available implementations of that dependency.
Service Locator patterns are more difficult to test and it certainly is more difficult to control dependencies, which may lead to more coupling in your system than you really want.
If you really want something like lazy instantiation you may still opt for the Service Locator style (it doesn't kill you straight away and if you stick to the container's interface it is not too hard to test with some mocking framework). Bear in mind, though that the instantiation of a class that doesn't do much (or anything) in the constructor is immensely cheap.
The container's I have come to know (not autofac so far) will let you modify what dependencies should be injected into which instance depending on the state of the system such that even those decisions can be externalized into the configuration of the container.
This can provide you plenty of flexibility without resorting to implementing interaction with the container based on some state you access in the instance consuming dependencies.