I'm working on an application that consists of many modules, with some having dependencies on other modules. I now decided to use Autofac to solve circular dependencies and improve the architecture in general.
To configure autofac I use the xml method (http://code.google.com/p/autofac/wiki/XmlConfiguration).
Now I am not sure on how to implement Autofac. Do I need to have a reference to autofac in each module in my application? Meaning that i have to register all components each time I want to solve a dependency...
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new ConfigurationSettingsReader("autofac", configPath));
IContainer container = builder.Build();
IWhatever w = container.Resolve<IWhatever>();
Is this the way to do it?
Or is it better to Wrap Autofac in a separate Module ?
With this approach I would have to register the modules only once (when the application starts) and could just use the wrapped Autofac to resolve dependencies...
IWhatever w = container.Resolve<IWhatever>();
I hope someone can tell me the best way to use Autofac.
thanks!
Each project need to have a dependency to the autofac core package if you would like to use autofac modules.
Use autofac modules as described here: http://autofac.readthedocs.io/en/latest/configuration/modules.html
Update
I describe why you should use modules here: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci
Separate module for container is not only a better option, it is the only right option. AFAIK IoC container instances must be singletons.
At least I've used Unity this way - you create publicly available static instance of container, initialize it on application startup and then access it from all your modules.
Related
I've been looking through the Simple Injector documentation and thought I was doing things right regarding Crosswiring, but alas...
I have the following which fails to resolve my App through the IServiceProvider
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SimpleInjector;
using SimpleInjector.Lifestyles;
using SimpleInjectorTesting;
Container container = new Container { Options = { DefaultScopedLifestyle =
new AsyncScopedLifestyle()}};
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Information))
.ConfigureServices((hostBuilderContext, services) =>
{
container.RegisterSingleton<App>();
services.AddSingleton<ISaySomethingService, SaySomethingService>();
services.AddSimpleInjector(container);
})
.Build();
host.Services.UseSimpleInjector(container);
container.Verify();
var app = host.Services.GetRequiredService<App>();
//var app = container.GetInstance<App>();
await app.Run();
If I switch to use the container.GetInstance<App>() call the it works fine, SI can resolve services registered from IServiceCollection.
If I set options.AddLogging() to SI, an IServiceProvider registered type can't receive ILogger even if I'm using container.GetInstance<App>()
System.InvalidOperationException: 'The configuration is invalid. Creating the instance for type App failed. The registered delegate for type ISaySomethingService threw an exception. Failed to resolve ISaySomethingService. ISaySomethingService is a cross-wired service, meaning that Simple Injector forwarded the request the framework's IServiceProvider in order to get an instance. The used Microsoft.Extensions.DependencyInjection.ServiceProvider, however, failed with the following message: "Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'SimpleInjectorTesting.SaySomethingService'.". This error might indicate a misconfiguration of services in the framework's IServiceCollection.'
So I have this library that does a bunch of stuff using SI and leverages decorators, conditionals, etc that standard .NET DI makes difficult but I want this library to be usable by anyone who may not be using Simple Injector. I have an extension method to Register my framework and then another to use it which does the container.Verify() call to get the SI specific stuff tucked away. But then I can't resolve through IServiceProvider as per the code above. Is this even possible with SI and if so what am I missing?
Update:
This is my App class
public class App
{
private readonly ISaySomethingService _saySomethingService;
public App(ISaySomethingService saySomethingService)
{
_saySomethingService = saySomethingService;
}
public async Task Run(CancellationToken cancellationToken = default)
{
Console.WriteLine(_saySomethingService.Message());
}
}
When it comes to integration with an .NET Core or ASP.NET Core application, Simple Injector works very differently compared to for instance Autofac. This has to do with the design choices made by Microsoft and their incompatibility with Simple Injector's design. I discussed this in detail here and here.
But this is why choosing Autofac for your DI container in an ASP.NET Core application, Autofac ends up replacing the entire DI infrastructure, which means all application, framework, and third-party registrations will be made in Autofac.
When choosing Simple Injector, on the other hand, the Simple Injector container will run side-by-side with the original MS.DI container. This means that you, as an application develop, will register your application components as part of Simple Injector, while framework and third-party libraries that depend on the IServiceCollection abstraction, will effectively use MS.DI as their backing container.
The Simple Injector integration package for .NET Core, however, does allow a feature called "cross wiring" or "auto cross wiring", which allows the Simple Injector container to resolve services from the built-in MS.DI container to inject them into your Simple Injector-resolved application components. This feature is implemented using Simple Injector's unresolved type resolution. As there is no such feature in MS.DI, it's not possible to let MS.DI automatically callback into Simple Injector to fetch missing dependencies. You can always do this on a per-service basis by making an explicit registration to MS.DI though, e.g. services.AddTransient<IService>(_ => container.GetInstance<IService>()).
In the majority of cases, however, you shouldn't need to be able to 'cross wire' back from MS.DI to Simple Injector, because the dependency would typically go from application component towards framework (or third-party) abstraction; not the other way around.
But the fact that Simple Injector doesn't replace the built-in DI infrastructure (but run side-by-side) does have the consequence that adding registrations to the IServiceCollection doesn't add them to Simple Injector. And this means that if you have a third-party library (or self-built NuGet package) that integrated with IServiceColllection, this won't run as part of Simple Injector.
Under normal conditions this wouldn't be a problem, because its okay for framework and third-party components to be composed by MS.DI, especially because Simple Injector makes it easy to pull them in. You, as an application developer, would typically don't see the difference (although it's important to understand what to register where).
But your case is different, because you are building a reusable library with application-specific abstractions (and implementations) while you want to simplify registration for the application developers using these abstractions. Adding a AddMyReusableLibrary(this IServiceCollection) method to that library will work when the end application is completely relying on MS.DI or Autofac, but won't help when the application uses Simple Injector.
There are a few options here:
You build an extra NuGet package, say MyReusableLibrary.SimpleInjector that depends on both MyReusableLibrary and SimpleInjector, and adds an AddMyReusableLibrary(this SimpleInjector.Container) method, or
You simply document what registrations need to be made to Simple Injector. It will typically be a handful of registrations. This gives the application developer full control and knowledge about the made registrations, although, admittingly, does cause some more code in the application's Composition Root, and doesn't allow new features in vNext of your MyReusableLibrary to get automatically added.
You design your reusable library according to Mark Seemann's advice on DI-friendly libraries. Although, in your case that unlikely helps because your reusable library actually contains application abstractions. It is a reusable library as in -it is a NuGet package-, but in fact contains parts of the application's core design and domain.
I'm writing the Windows service Listner for Active MQ. I'm trying to implement Dependency Injection in the project. But i'm not sure where to register Container and how it will be resolved ?
I tried to put it in OnStart method as below, but no luck.
protected override void OnStart(string[] args)
{
container = new WindsorContainer();
// IWindsorContainer container = new WindsorContainer();
//container.Install(FromAssembly.This());
container.Register(
Component.For<IHttpClientProxyHandler>().ImplementedBy<HttpClientProxyHandlerWeb>().LifestyleTransient(),
Component.For<IHttpClientProxy>().ImplementedBy<HttpClientProxyWeb>().LifestyleTransient(),
//Component.For<IRedisCacheClient>().ImplementedBy<RedisCacheClient>().LifestyleTransient(),
Component.For<IApplicationSettings>().ImplementedBy<ApplicationSettings>().LifeStyle.PerWebRequest,
Component.For<ILogger>().ImplementedBy<Logger>().LifeStyle.PerWebRequest
);
this.messagingQueue = new ActiveMessagingQueue(new ApplicationSettings(), new Logger());
this.logger = new Logger();
this.applicationSettings = new ApplicationSettings();
this.httpClientProxyHandler = container.Resolve<IHttpClientProxyHandler>();
this.messagingQueue.OnMessageReceived += this.OnListenerMessage;
}
Then i tried to put in ServiceBase Constructor- no luck . Even tried putting it in Main function. But im getting below error always in event logger.
'Namespace.HttpClient.HttpClientProxyHandler' is waiting for the following dependencies:
- Service 'Castle.Windsor.IWindsorContainer' which was not registered.
Can anyone help here?
I agree with Patrick that you shouldn't be depending on IWindsorContainer (or IKernel) in your registered components. Instead, depend on the components (or rather, the interfaces those components implement) you need, make sure they're also registered in your container, and let Castle Windsor resolve the whole dependency hierarchy for you.
Why shouldn't you provide a mechanism for resolving dependencies to each component? Well, it hides the actual dependencies of your component and makes mocking/stubbing them in tests more difficult as you have to mock the service locator and the actual dependency. It also pushes responsibility for the management of dependencies on to you; In Castle Windsor if you explicitly Resolve a component it's best practice to also Release it when you're finished. Finally it couples your components to the particular flavour of Dependency Injection you're currently using, I.E. Castle Windsor.
I would recommend implement it together with Topshelf framework. You can see similar example here:
https://github.com/EasyNetQ/EasyNetQ/wiki/Wiring-up-EasyNetQ-with-TopShelf-and-Windsor
Instead of ActiveMQ they use EasyNetQ, but basically the problem should be the same.
So, this is the first time I'm dealing with DI, please correct me if I misunderstood the whole DI thingy.
These are few of my projects:
Web Application/ Web API Project - Depends on Service Class + inject Automapper (Configuration only applicable for current project)
Service (Class Library) - Depends on Data Class + inject Automapper (Configuration only applicable for current project)
Data (Class Library)
My intention was to have each project having its own DI container (says Unity DI). I'm not sure that each project can have its own DI container.
I have read some of the article, showing that it cannot be done (not sure if i interpret them correctly) but I'm not sure why?
If it cannot be done, can anyone explain it and how can I achieve this and I doesn't want to register the classes in Data Layer in the Application Layer DI.
If each project can have its own DI, when registering the IMapper as instance will it override IMapper of other layers?
My intention was to have each project having its own DI container (says Unity DI). I'm not sure that each project can have its own DI container.
As explained here, you should compose all object graphs:
As close as possible to the application's entry point.
This place is called the Composition Root:
A Composition Root is a (preferably) unique location in an application where modules are composed together.
In other words, the only place that you should use your DI container and configure your application's dependencies is in the start-up project. All other projects should be oblivious to the container and should purely apply Constructor Injection.
I have read some of the article, showing that it cannot be done
It can be done, but you shouldn't.
If each project can have its own DI, when registering the IMapper as instance will it override IMapper of other layers?
This problem goes away if you apply the Composition Root pattern. In the Composition Root you have full control over which component gets which dependency.
PRO TIP: Read this book.
I have the following code snippet in my application:
services.AddScoped<IMyInterface, MyService>();
services.AddSingleton<IYourInterface, YourService>();
Due to some environment initialization process, I have to be able to obtain the singleton instance of IYourInterface within Startup class to call the service to read a couple of configuration entries from a remote server and populate them. How can I achieve this goal considering the fact that I am using .Net Core's built-in DI framework?
The way to do this to create this instance manually up front as follows:
var service = new YourService();
services.AddScoped<IMyInterface, MyService>();
services.AddSingleton<YourService>(service);
Just as it is wise to separate the registration process from use (as the Microsoft.Extensions.DependencyInjection library correctly forces), this kind of separation is important between loading/building configuration and making the container registrations. Doing register-resolve-register is unsupported by libraries like MS DI, Autofac and Simple Injector, because it can lead to lots of complexity and subtle bugs.
Guys I need your help I am using Castle Project Windsor IoC container in my C# Winforms application. I have services classes which has DI by constructor passing in implementing Repositories. I used Windsor to register them all Component.Register(...etc but everytime I use my service class I am calling resolve. for example:
var employeeService = container.Resolve....etc
is there any other way not having to call resolve all the time?
in ASP.NET you can just register them all then set the Controller factory: ControllerBuilder.Current.SetControllerFactory(new WindsorIoCFactory());
with this I can just use my controllers(using services) directly without calling resolve. how do you do this in winforms?
You should use a Composition Root approach.
In short, you should use Resolve only once at the App-StartUp basically resolving the MainView and through that you should be able to obtain all views(most likely through a TypedFactory) and their dependencies with no explicit Resolve call.
Service locator approach, as per comment link, is a deprecable anti-pattern specially when Composition Root can be used instead.
On the windsor wiki you'll find a sample based on a Silverlight app, very close to a Winform scenario.