I want to be able to configure ASP.NET's dependency injection framework to be able to resolve me an instance of Common.Logging's ILog interface. Creating an instance of ILog is done via the Common.Logging's static LogManager.GetLogger methods which require a type as a parameter.
This means that when resolving an instance of ILog I need to know the target type that the DI engine is trying to inject into. In the past I've used autofac modules to solve this problem which other have asked about here, but it would nice to be able to do this purely with ASP.NET's built in Ioc.
I can see that there is the ability to resolve an instance by creating a method that takes an IServiceProvider, but there is no context of the type being injected into that I can see.
Does anyone know how a service can be resolved at runtime with knowledge of the type its being injected into?
I posted the same question in the ASPNET dependencyinjection repo issue register and apparently its not possible.
Related
I have a web forms application (myWebForms)
I have a class library project (myClassLibrary) that has a class called "myClass"
WebForms references myClassLibrary
I have added Autofac references to the web forms application, set the global asax to resolve "myClass" etc...
I can see that in my aspx code behind, the public property I added for AutoFac, is instantiated correctly by AutoFac.
All this is great so far, however, my actual project is a lot more complex than this, and what I need to do is have access to the resolved "myClass"
From within myClassLibrary
How do I achive this? (do I inject the container into myClass from the web forms project?, do I somehow reference the web forms global property, or do I build the container again within myClassLibrary?)
First, I'd recommend checking out the Autofac documentation on web forms and quick starts. I think you may have a lot of questions answered by doing that, though I understand it's a lot. DI is complicated, and I'm afraid that providing just a "quick answer" here may lead you to an incorrect understanding of what's going on.
Autofac quick start
ASP.NET Web Forms Integration
Working example of web forms integration
In general...
You register types with Autofac that you want to inject. This includes all the types your web forms will need as well as all the dependencies those types will need.
Autofac, via its integration, will resolve dependencies and put them in your web forms. If those objects also have dependencies (e.g., constructor parameters), then Autofac will also figure those out automatically and plug them in.
Say your web form needs a property called IEmailSender...
public IEmailSender EmailSender { get; set; }
Your email sender object may need some other dependency, like a network socket factory or something.
public EmailSender(ISocketFactory socketFactory)
You would register both of these in the container. It doesn't matter which assembly they come from. You have to register them into the Autofac container for it to work.
builder.RegisterType<EmailSender>().As<IEmailSender>();
builder.RegisterType<TcpFactory>().As<ISocketFactory>();
When your web form gets the IEmailSender, Autofac will resolve the TcpFactory first, then provide that in the constructor of EmailSender, then that will be handed to your web form.
Again, a lot of this is covered in the docs and examples. While I realize there's a lot and it can be overwhelming, I strongly urge you to walk through that info because it can save you a lot of time and pain in the long run.
I'm building a new asp.net webapi application that may use asp.net MVC controllers later.
I'm going to use Unity as an IOC + Lifetime resolver to handle my objects.
I want all my types to be resolved in one place.
I've read about the IDependencyResolver which provides a service-locator(I know it's an anti-pattern) and it seems to fit my goals.
I've tried to find the "scope" of this IDependencyResolver and couldn't.
What I did see is that's he's under System.Web.Mvc - that kinda made me think about his "scope".
When does he "start" his job in the asp.net application lifecycle?
Will he resolve HttpModules as well? Or does he "kick in"
My Global.asax code will look something like this:
ApplicationUnityResolver resolver = new ApplicationUnityResolver(ApplicationContainer._container, DependencyResolver.Current);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
DependencyResolver.SetResolver(resolver);
My ApplicationUnityResolver is:
System.Web.Mvc.IDependencyResolver and System.Web.Http.Dependencies.IDependencyResolver
I think it is fairly early in the MVC pipeline the DependencyResolver get instantiated. MVC framework internally use the DependencyResolver. As you know the DependencyResolver finds and create instance of Controllers, during the Controller creation. Which is right after the IRouteHandler i.e MvcRouteHandler get invoked - fairly early in the life cycle.
But it is well after the HttpModules get created, I think you are out of luck using the DependencyResolver to register HttpModules.
I don't think you cannot customize the scope of the IDependencyResolver. It is just Service Locator type container which helps you to plugin your own dependency resolution mechanism.
Yes IDependencyResolver is an anti-pattern and I personally don't like it. Actually
Mark Seemann has a really good article on the IDependencyResolver. I'm sure this would point you to the right direction.
You better off using the Composition Root pattern to register dependencies in a single location.
Is it possible to do property injection with the OrchardCMS?
I know that Orchard uses Autofac and that Autofac does do property injection, but I need to know how to do property injection for the IOrchardServices interface.
Our team is looking at Orchard but our code base is all in ASP.NET 4.0 WebForms and so we will continue to serve aspx pages and slowly migrate those said pages into Orchard as time permits.
With that, we'll need a way to get access to the OrchardServices object. I'm thinking that this is something I'd have to come up on my own. Does any one have any good examples of performing property injection in Orchard?
It's pretty simple - look into the source how it's done with ILogger interfaces and do the same for IOrchardServices. The source file is Orchard.Framework/Logging/LoggingModule.cs. It's exactly what you are looking for, I guess.
Everything is being done via Autofac module (implementation of Autofac.Module class). What that class does is to:
register the implementation of ILogger interfaces (Load method) and
get properties of the processed object and set appropriate ones to object resolved from the container (AttachToComponentRegistration method).
Pretty simple. Autofac modules are a nice way to plug into the DI process.
It would be enough just to copy that source file to your custom Orchard module and changing ILogger to IOrchardServices (and, of course the registered class). The class I mentioned makes use of factory pattern to create instances, but you can change that to simple object creation via new and get rid of the factory-related things.
I made a custom SessionStateStore provider, however the dependencies were not resolving. I used Unity for DI.
I googled a lot about this problem and got some useful hints, but still I can't get it right.
the providers are constructed and managed by the framework, and there is no opportunity for us to intercept that construction to provide additional dependency injection
override the Initialize() method in your custom provider, and do the dependency injection there
There's a similar problem and a decent solution here and here(StructureMap, not Unity), but I can't get it right.
Please help. Thanks.
Providers are really painful things. There's really no nice way to address this problem, but a practical way is to handle the provider as a Composition Root - in other words, as if it was the entry point of the application. Within the provider you can compose all of your services.
If you use a DI Container (like Unity) you can store the container instance in HttpContext and get it from there to compose your object graph from within the provider.
I want to isolate all my code from the IoC container library that I have chosen (Unity). To do so, I created an IContainer interface that exposes Register() and Resolve(). I created a class called UnityContainerAdapter that implements IContainer and that wraps the real container. So only the assembly where UnityContainerAdapter is defined knows about the Unity library.
I have a leak in my isolation thought. Unity searches for attributes on a type's members to know where to inject the dependencies. Most IoC libraries I have seen also support that. The problem I have is that I want to use that feature but I don’t want my classes to have a dependency on the Unity specific attribute.
Do you have any suggestions on how to resolve this issue?
Ideally I would create my own [Dependency] attribute and use that one in my code. But I would need to tell the real container the search for my attribute instead of its own.
Check out the Common Service Locator project:
The Common Service Locator library
contains a shared interface for
service location which application and
framework developers can reference.
The library provides an abstraction
over IoC containers and service
locators. Using the library allows an
application to indirectly access the
capabilities without relying on hard
references. The hope is that using
this library, third-party applications
and frameworks can begin to leverage
IoC/Service Location without tying
themselves down to a specific
implementation.
Edit: This doesn't appear to solve your desire to use attribute-based declaration of dependency injection. You can either choose not to use it, or find a way to abstract the attributes to multiple injection libraries (like you mentioned).
That is the basic problem with declarative interfaces -- they are tied to a particular implementation.
Personally, I stick to constructor injection so I don't run into this issue.
I found the answer: Unity uses an extension to configure what they call "selector policies". To replace the attributes used by Unity, you just code your own version of the UnityDefaultStrategiesExtension class and register you own "selector policies" that use your own attributes.
See this post on the Unity codeplex site for details on how to do that.
I'm not sure that it's going to be easy to do the same if I switch to another IoC library but that solves my problem for now.
Couldn´t you just setup your configuration without the attributes, in xml. That makes it a bit more "unclear" I know, personally I use a combination of xml and attributes, but at least it "solves" your dependency on unity thing.