Are there any equivalent for following method from Microsoft Dependency Injection in Autofac.
ActivatorUtilities.CreateInstance(serviceProvider)
There is no direct analog for ActivatorUtilities in Autofac. But you have options.
You can directly resolve things that are registered (service location) - lifetimeScope.Resolve<T>()
If you need to resolve any type at all rather than only things you've registered, AnyConcreteTypeNotAlreadyRegisteredSource can help.
You can inject properties into constructed objects - lifetimeScope.InjectProperties(obj)
Or, if you really need ActivatorUtilities, you can use the Autofac.Extensions.DependencyInjection package to create a Microsoft container backed by Autofac and use the utility methods directly.
Related
I have 4 Projects in a solution
DAL_Project
BLL_Project
Interface_Project
WebApi_Project
Interface_Project has two interfaces ICar_DAL and ICar_BLL
DAL_Project has a class Car_DAL that implements ICar_DAL
BLL_Project has a class Car_BLL that implements ICar_BLL and its constructor takes in ICar_DAL
WebApi_Project has an api controller CarApiController and its constructor takes in ICar_BLL
the dependency resolution of WebApi Controller's constructor is done by Unity.WebApi using this in Bootstrapper.cs:
container.RegisterType<ICar_BLL, Car_BLL>();
this would have worked if my Car_BLL further didn't require ICar_DAL in its constructor.
to make it work i can do some thing like this:
container.RegisterType<ICar_BLL, Car_BLL>();
container.RegisterType<ICar_DAL, Car_DAL>();
but that would mean that i need to add reference to DAL_Project in my WebApi_Project which is something i would never want to do. DAL_Project should only be referred by BLL_Project
How can i solve this issue?
but that would mean that i need to add reference to DAL_Project in my
WebApi_Project which is something i would never want to do.
Oh you seem to have some misunderstanding about how Dependency should be done if you don't want to do that. The DI container is configured in the outermost layer of your application which is actually the host. It is also referred to as the Composition Root. In your case this is the hosting application of your Web API. If you are using ASP.NET to host your Web API then this is the right place to do the composition root and reference all the other underlying projects.
Personally in complex project I tend to have a ProjectName.Composition class library which serves me as a Composition root. this is where I configure my DI container and this is the project that references all the others - coz obviously in order to configure your DI root you need all the dependent projects and implementations. This .Composition assembly is then references in the hosting application and the Bootstrapper.Initialize method called in the Initialize method of the hosting application.
In the case of ASP.NET host that would be Application_Start in Global.asax
In case of a desktop application or a self-host that would be the Main method which is the entry point.
I am trying to properly use Ninject to inject log4net logging into my MVC3 application. I am using the Ninject.MVC3 package, so I have the NinjectMVC3 class that automatically extends the App_Start method and contains the RegisterServices method that binds all dependencies. I also have the Ninject.Extensions.Logging.Log4Net package, but I don't know how to use it. I already know how to configure log4net in my web.config, but don't know how to use this extension for DI.
I have read all the following articles/posts, but none of them seem to define how to properly setup a project for DI logging.
At http://dotnetdarren.wordpress.com/2010/07/29/logging-in-mvc-part-4-log4net/, Darren
provides a great article, but doesn't seem to deal with DI (at least I don't see it).
At Using Ninject to fill Log4Net Dependency,
Remo Gloor states here that the extensions should provide all that's needed for implementation, but it doesn't show the code of how to instantiate it.
The documentation for ninject.extensions.logging at https://github.com/ninject/ninject.extensions.logging/wiki/Using is very limited at best. I have re-read it many times, and still don't see how to use bind the injection in the NinjectMVC3 class, or concrete examples of how to call the logger from my controller class for example.
At the most promising article, Moosaka provides some great code at Ninject.Extensions.Logging.Log4net unexpected behavior, but when I try it, I get a compile error in the LoggerFactory at ILogger logger = new Logger(type); stating "Cannot access protected constructor 'Logger' here". Also, he states to "Tuck this whole mess away into a separate class library". Does that mean as a whole separate project?
I'm just getting lost in all the differing options and dated posts and would like any input on how to use Dependancy Injection with Ninject and Log4Net in my MVC3 project. Also, if it matters, all of my Ninject code is in my domain project, but the logging needs done from both the domain and web project (and mocked in my unit tests). Any help is appreciated.
You shouldn't have to configure anything except the normal log4net config.
All you have to do is to inject a ILogger wherever you want to log.
https://github.com/ninject/ninject.extensions.logging/wiki/Using
While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data, where all the implementation details live. Contracts, like IAccountRepository, live in library MySite.Contracts. Now, if I reference this MySite.Data library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
MySite.Data knows nothing about MVC project
MVC project knows the concrete repositories types to provide correct container registrations.
You can make life simpler with StructureMap Registry objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.
I'd advise that you:
Use MVC3 and drop your custom IControllerFactory if you only use it for DI into your Controllers.
Use StructureMap Registry objects to provide each and every IoC registration ever needed.
Use StructureMap Assembly scanning capabilities to provide components discovery.
Use something much more common as a DependencyResolver, i.e. not a StructureMapControllerFactory but a CommonServiceLocator with StructureMap adapter instead.
Try to abstract from StructureMap itself inside your main app.
And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.
My app is set up this way
Web
Data
Services
POCO Entities
Controllers use services (so they should be injected)
Services use Repositories (which I assume should also be injected)
I have this already set up so that the Controllers receive the service they need through Ninject but I not sure how to get this done with the services =>repositories
any help with this?
You could use the ninject.web.mvc extension. It contains a sample application which illustrates how you could register the container in Global.asax.
Bob has several blogs about repository pattern with Ninject and NHibernate. It's pretty much the same for all other OR Mappers:
http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/
http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
http://blog.bobcravens.com/2010/09/the-repository-pattern-part-2/
Simply set up your services' dependencies as well as the controller's dependencies. Ninject will walk the dependency chain and resolve all of them.
for example,
ProductController has dependency on IProductService
IProductService is implemented with ProductService that has a dependency on IProductRepository
IProductRepository is implemented with NHibernateProductRepository that has a dependency on ISession.
when your NinjectControllerFactory attempts to resolve ProductController, it sees the dependency on IProductService. it resolves that dependency as ProductService, and sees that it has a dependency on IProductRepository. and it will continue on down the chain until it can resolve completely an argument.
so the important part is to Bind ANY dependencies, not just those in a Controller.
I use structure map for dependencies injection, I also now want to use postsharp for some authorisation checking at my service layer. because my service layer has all injected repositories is there a way I can inject or pass these repositories to the postsharp attribute to query the sql and provide authorisation?
I've never used PostSharp - does the code in the PostSharp attributes execute at runtime, or during a post-compile pre-runtime stage?
If the code executes at runtime, you should be able to do service location using a static gateway (ObjectFactory.GetInstance).