MVC with 3Tier Architecture, Entity Framework and DependencyInjection [duplicate] - asp.net-mvc

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
DAL -> BLL <- GUI + composition root. How to setup DI-bindings?
I'm defining a new solution and i've created some projects:
WebUI
Domain (contains my entities)
BusinessLayer (contains my business rules)
DataAccessLayer (contains my Abstract and Concrete implementations of my repositories)
Every project has a reference for my Domain.
In every example i see in Internet, the dependency injection (ninject) is defined in WebUI, but i cannot do that because it'll require me to add a reference for my DataAccessLayer.
If i move the binding association to the BusinessLayer then my WebUI will not become database agnostic because the bindings are hardcoded in my BusinessLayer.
Please give your opinion (even in the architecture), and why i'm having decision implementation problems?
thank U ALL

You would normally configure the container in the application project. In your case the ASP.NET MVC application. This configuration will need to reference all assemblies in your solution. This is normally not a problem. Just don't use the DAL library from the rest of the web application.
If that is a problem for you, create a special Bootstrapper project that references all projects and configures the container. Then call that project from within your Application_Start event.

It's ok if you have references to your data access layer in web app, so long as you don't actually reference them in your code (other than in your ninject configuration). The reason is that Ninject is configured in code, thus to change your configuration you have to change the code.
If you want a purely file based configured approach, then you would need to use a different Container, or develop a file based configuration based on Ninject.
So long as your CODE is database agnostic, all you have to do is change your ninject code and modify the references and you're good to go, you don't have to change your app.

Related

ASP.NET Core: Correct pattern to pass DbContext to separate class libraries?

This is really a question about what would be a recommended pattern...
I use ASP.NET Core 2.0 and use dependency injection to allow my controllers and other classes to have access to a IMyDatabaseRepositor, via class constructors.
I also have several other projects in separate assemblies. I was thinking of allowing these other projects do some repository work as well. We're really talking about providing access to an existing DbContext.
Should I somehow pass the IMyDatabaseRepository instance to methods in the other project classes, or should those classes simply instantiate their own IMyDatabaseRepository (and do all their own "Startup" and connection string stuff for database and DI)?
I'm not sure if the other project classes can use the IServicesCollection somehow as well in order to get DI instances from my main ASP.NET Core web app.
Any thoughts?
Libraries should not compose object graphs, only the startup project should.
This means that in the library you simply use Constructor Injection, while in your Startup class you register all components from all libraries.

What is the correct way to share a project across Web and Winforms/console solutions?

I am converting a .NET 2.0 Winforms applications to ASP.NET MVC3. The Winforms solution uses several projects for business logic, and the MVC application includes these projects. The projects are also used by a variety of Windows console applications.
The problem is that these projects use System.Windows.Forms.Application.StartupPath to find files they use, whereas for web development System.Web.HttpRunTime.AppDomainAppPath is used.
I would prefer that both solutions use the same projects and that these projects are modified as little as possible as they are large, old, and relatively undocumented. What is the correct way to address this issue?
Right now I am thinking that I would create a new configuration with each project that would define WEB, and then use #if/#else statements to include the correct depedency and to define the return of the getPath() method.
Before you start plaguing your code with preprocessors, you should consider creating an interface IApplicationConfigurator or IApplicationStarter
public interface IApplicationStarter
{
string GetPath();
}
And inject it with a MvcApplicationStarter or a WinformsApplicationStarter depending on your application. You can then have your project libraries have a dependency on the IApplicationStarter interface. It should require minimal implementation on the projects, and you can reuse the pattern for other common dependencies. Look into dependency injection frameworks as it takes this approach into the next level.
This is what class libraries are for. Create a class library project, move all the common bits there, and then have a separate WinForms and MVC project that both reference your class library.

DI/IoC MVC Assembly Reference issues and abstraction [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Ioc/DI - Why do I have to reference all layers/assemblies in entry application?
I've decided to build a new MVC 3 application using Autofac as the DI container.
Since all my container configuration is done within the MVC project it forces a reference to all layers e.g. Data, which ideally the web project should have no idea about.
Is there a simple way to move this to a separate "fabric" class library? The problem I'm encountering is that I can't then configure the controllers in the fabric project as it would result in a circular reference between Fabric and MVC projects.
I understand that the reference is only used for configuration but not having the references will ensure a naughty developer doesn't start referencing the classes directly.
On a related note does anyone have any feelings about abstracting their DI container - or is this just getting carried away! As a rule of thumb I think it's good practise to wrap third party assemblies but at this level?
Thanks in advance,
Tom.
Since all my container configuration is done within the MVC project it
forces a reference to all layers e.g. Data, which ideally the web
project should have no idea about.
If you don't reference those layers, how do you expect the corresponding assemblies end up in your bin folder at runtime? You shouldn't be worried for referencing those layers in the MVC application.
but not having the references will ensure a naughty developer doesn't
start referencing the classes directly.
You should teach your developers good practices.

What's the best design for this problem with IoC and Circular Reference

I'll try to explain in the simple way.
I have a solution (c# 4.0) that contain 4 projects
Framework
DAL
Domain
WebApplication
So my question is:
Framework is the right place to configure my Unity IoC? I want to configure via code and not with xml, so Framework need to know reference of DAL but DAL already knows Framework.
All my projects will know Framework, so where i configure my IoC?
Applications should be configured in the Composition Root, which is as close to the entry point as possible. In your case, that would be the WebApplication. That's the only project which should have a reference to Unity. None of the other projects should have any reference to Unity at all.
In the composition root, you should follow the Register Resolve Release pattern.
See also this answer - it talks about Ninject instead of Unity, but the concept (and hence the answer) is the same.

DAL -> BLL <- GUI + composition root. How to setup DI-bindings?

I have made a three-layer application with refrences going as described in this answer:
DAL with Repositories -> BLL with services and IRepository <- Asp.net mvc-app
To get this running with dependency injection I see a few options:
1. Add a reference to DAL from the web-app to be able to setup bindings on application start.
2. Use a container with xml-configuration
(3. Use reflection to load the dal-assembly and find types)
Option 1. is easy and also makes the DAL.dll be copied to bin but then I suddenly reintroduce the reference I worked so hard to get rid of. The repositories can now be accessed directly. Option 2 and 3 seems unnecessarily complex.
Is there no other way?
Split up the ASP.NET MVC application in two:
One part is your original ASP.NET MVC application, but without any logic whatsover. Just keep the Composition Root and your Views (.aspx, etc.) in this project. Since this is the Composition Root, you can have references to all your other projects. However, since all logic would have been extracted, this is now a Humble Object, so it's okay to have all the references at this level.
Extract all the logic (Controllers, etc.) into an Application Model project, which would just be a normal library project (.dll) that references the ASP.NET MVC binaries. This project would need to reference the BLL to get at the interfaces, but that's okay. However, both the Application Model and the BLL are effectively shielded from the DAL.
The resulting layering would look like this:
ASP.NET MVC application
Application Model
BLL
DAL
Mark Seemann's answer gave me the idea for this variant:
DAL with Repositories -> BLL with services and IRepository <- Asp.net mvc-app
^------------------------^--------- Composition Root <-------ยด
This is meant to illustrate that instead of letting the Web project reference the DAL it references a separate Composition Root-project that references both DAL and BLL. The composition-root-project has a single class with one method that define the bindings. It gives these additional benefits:
Only three layers. Four layers would be a tough sell in the team.
Loose coupling is ensured. It is not possible to access the DAL from view-code.
Better tool support. Controllers remain at the standard location so "Add Controller" is accessible on the context-menu and missing views are highlighted in the controller-code. Also there is no need to configure or write a custom controller factory.
I don't see any big drawbacks.
Just go with Option 1.
Just because you have a reference to the assembly doesn't mean your breaking the SoC.
The Web Project still knows nothing about the underlying implementations, only the interface.
The Web Project is the "aggregator" of the below layers therefore it makes sense it should know about them in order to configure them.
I split the MVC project in two roughly as described in Mark Seemans Answer.
The MVCApplication is a humble object and requires references to everything, but doesn't have any of the MVC code, apart from global.asax (which it needs) and web.config (which it seems to want).
The MvcUI project only references interfaces and uses dependency injection.
If you put both the projects (.csproj files) in the same directory then the Content, Controllers, Models, Scripts and Views folders are all actually in the same place, so all the tooling works.
The picture of the solution below shows the idea.
The directory structure looks something like this
And you end up with a Dependency graph like this
Recently i was following the same thing and figured about the MEF (Managed Extensibility Framework). With the help of MEF and reflection you can get rid of that DAL/Unit of work reference from your composition root and you don't need to have 2 mvc projects as discussed above.

Resources