I'm trying to use Simple Injector in a project which has the following architecture :
DAL layer(owns a repositories),
BLL layer(owns a services that talks to the repositories),
MVC layer(talks to the services in the BLL layer).
when it comes to register with the container the classes and the interfaces, I`m facing a problem, Simple Injector needs me to register the repository with its interface (as my classes in the service layer accepts a repository in their constructor)
So, actually, Simple Injector forces me to add a references to my DAL layer in my MVC layer which i really like to avoid.
My question is, is it possible/right to make an external project that will hold only Simple Injector, and this project will have reference to all other projects and that way i would be able to register what i want and still keep my project abstraction?
or there is any other easy way to solve this ?
A DI Container (e.g. your Simple Injector) should only be referenced from the Composition Root. All other modules should have no reference to the container.
You can read more about the Composition Root here:
http://blog.ploeh.dk/2011/07/28/CompositionRoot/
What is more DI Container should be applied using the Register Resolve Release pattern entirely from within the Composition Root.
More about this pattern here:
http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/
Related
I was reading about ASP.NET Core features and I decide to transfer my current solution ( MVC 5 ) to MVC 6 but I got a little bit confused regarding integrated DI.
Currently I have this architecture
CemaManager ( representative layer ) has reference to Helpers, Resource, ViewModel and BLL.
Bll has reference to ViewModel, Database and DLL.
Dll has reference to Database.
Typical N-tier architecture using DI and Repository pattern.
When I investigate MVC6 there is startup.cs where DI initialize.
That means if I want to separate BLL and DAL they will have all reference to MVC6 and all logic will go thru that layer? By the time It's gonna be heavy and hard to maintain and scale or am I wrong?
Is there any way to export startup.cs or DI method to another layer?
Maybe somebody know any articles to read or examples?
Personally I have a few things I would change about the overall structure, but I'm guessing a full design review isn't really what you're asking for. ON your actual question, no - your other layers do not need to reference MVC.
For most any application, IoC needs to be configured and initialized in the presentation layer. Ultimately your presentation layer needs a reference chain (direct or indirect references) to everything you want to register, but this has always been true.
You are already referencing Helpers, Resource, ViewModel, and BLL so you can easily register implementations for the interfaces in those layers. You could also add a reference to DLL to register implementations from that layer.
You can also go the indirect route and add a class in each layer which takes a reference to your IoC container and handles its own registration. In Autofac this is done using modules but there are equivalent ways of accomplishing the same thing using other IoC containers.
I'm starting to use the Windsor Castle IoC container. The web app is ASP.Net Web forms, and there is a class library of business objects that I'm trying to add DI to.
I am initializing the Windsor Container in the Global.asax Application_Start method. I really will only want the container to be used in the Business Class library. The Class library doesn't know about the web application. It's in a different project.
What is the preferred way to initialize and resolve objects in this scenario?
i don't think you should use a DI container in your BL. this is the whole point with DI. object composition can be done in a variety of ways and this is determined in the composition root of your application. your composition root is not in your BL therefore the BL should have no reference to Castle Windsor. your composition root (the place where the objects are actually composed, where dependencies are actually resolved) is your web application project. it is there that you should decide how to compose your object graph: use Windsor, another container or poor man's DI.
also, creating the composition root in a web forms app is a little tricky. you can read more about this in 'Dependency injection in .net' by Mark Seemann p224-p230
I am pretty new to MVC and I am currently working on an MVC 3 project in visual studio and I want to create a method or variable that is accessible globally. When I say globally I mean available in my web project, service layer project, and data layer project.
I guess when I say global I mean global to the entire solution.
I tried creating a class in the solution items folder and referencing in my web project but its not letting me add a reference to the class since it is not a DLL.
I am a little confused with how to do this. Any suggestion would be appreciated. Also keep in mind that though I am a programmer I am still somewhat new to MVC and programming.
Edit: I have also tried adding a method in the global.asax file but was unable to call it
You should create a shared assembly where you define the class. You can then add a reference to the shared assembly from all projects that need the feature.
The class that you want to be "global" sounds like some sort of service. I suppose this is the kind of thing you may want to do with a logging service for example.
Using a logging service as an example it is generally best practice for the interface to the logging service be defined in a lightweight contracts type assembly. Then any of your assemblies that require an implementation of ILoggingService should inject the necessary implementation using an IoC container such as Autofac or MEF.
This pattern is pretty common and allows you to share common services while keeping implementations loosely coupled. Also this pattern will lead to highly testable code as fake implementations can be injected with Moq
I'm trying to figure out how separation should work with ASP.NET and dependency injection.
I have four projects:
ASP.NET Client
BusinessLogic class lib (BL)
Integration class lib, calling Service references
Shared (Interfaces, Models)
In Integration I have a repository, which calls other services. The repository "MyRepository" implements an interface "IMyRepository", which is placed in Shared, and returns objects which are also placed in Shared.
Strictly speaking, I would not like a reference/dependency from the Client to the Integration-project, but all communication should happen through BL.
In the Client's Global.asax, I register my types with Autofac
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<MyRepository>().As<IMyRepository>().InstancePerHttpRequest();
However this requires the Client-project to reference the Integration-project for the implementation of MyRepository. Should it be this way?
How can I not have a reference from Client to Integration and keep the separation clean?
My real world project is on a much larger scale than this, so I'm trying to untangle the dependencies.
Thanks for your time!
My normal approach is:
Define a way to discover types in each individual assembly. Easiest approach (if you do not mind referencing Autofac in each) is to put an Autofac Module in each assembly. If you do not like that, you can define your own discovery abstraction (for example, MEF-like attributes).
Discover all assemblies. Easiest approach is to scan the bin folder, but you can use some custom configuration. I haven't checked latest versions of Autofac add anything in terms of module discovery, but previously I did it manually.
Use previously defined type discovery approach to register all relevant types from each discovered assembly.
I am using Castle Windsor for ioc in an MVC project.
My architecture is basically Web -> Services -> Data
The controllers have services as dependencies.
The services have repositories as dependencies in the data layer.
My Web layer does not have a reference to the Data layer. My problem is that I am trying to register my repositories which is a dependency of my services. If i have a separate container in my services layer that registers the repositories how should I bootstrap it?
Or I may be going about this in the wrong way.
How about this. The downside is that you need to hardcode the Name of your repository dll, but you could always move this to web.config etc which would be slightly cleaner.
IWindsorContainer container = new WindsorContainer();
// Register repositories
_container.Register(
AllTypes.Pick()
.FromAssemblyNamed("MyDataLayerAssembly")
.WithService
.DefaultInterface());
// Register services
_container.Register(
AllTypes.Pick()
.FromAssemblyNamed(typeof(ISomeService).Assembly.GetName().Name)
.WithService
.DefaultInterface());
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
You may just need to tweak precisely what's passed into the Register() methods to suit your needs however.
Your Web layer would not have to reference the data layer if you have placed the interafces of the datalayer functional classes ( AKA Repositories ) in the Domain layer. Then you can easily depend upon single container which is initialized in the web layer.
This Question contains further details.
Refer mvc extensions for some advanced way of achieving this.