Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Project EF Repository Pattern

If I use the Repository Pattern in an ASP.NET MVC Application I need DI to let the program know, to interface the classes must be mapped. If I implement Unity I need to add the DAL project to my MVC project, and then register the types in the global.asax.

In my mind, I think it's bad to add the namespace of the DAL Layer to the MVC project, there is a business layer also in between. I think, it would be beautiful to inject the DAL classes in the business layer and only the business layer mappings in the MVC app.

What's the way to go here? Do you have suggestions?

UPDATE: To make it clear to me. In the service layer, there are only DTO's and the DI for the business and data access layer. In the service layer I map the DTOs to the domain model. What I don't understand is, how can I call the business layer methods then?

like image 376
Dominik2000 Avatar asked Apr 02 '13 17:04

Dominik2000


People also ask

Do we need repository pattern with Entity Framework?

The single best reason to not use the repository pattern with Entity Framework? Entity Framework already implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository. Implementing another layer on top of this is not only redundant, but makes maintenance harder.

What is EF in MVC?

It is a data access framework which used to create and test data in the visual studio. It is part of . NET Framework and Visual Studio. The latest package is shipped as Entity Framework NuGet Package.

What is repository pattern in EF core?

Repository Pattern is an abstraction of the Data Access Layer. It hides the details of how exactly the data is saved or retrieved from the underlying data source. The details of how the data is stored and retrieved is in the respective repository.


2 Answers

If you want to be pragmatic, a true 3-tier architecture requires a service layer. Between the service and MVC are Data Transfer Objects (DTOs). The service layer hides both the DAL and the business layer.

If you set it up like this, the MVC itself knows nothing about DAL, only DTOs and Service (contracts).

like image 163
Alwyn Avatar answered Oct 08 '22 14:10

Alwyn


Even if you don't use a distinct service layer, you can accomplish what you want, which is to decouple the MVC application from the DAL project using DI.

The way to do this is to add a couple of projects/assemblies in between that wires up your IoC container with specific instances of the interfaces you have defined.

I typically use this naming convention:

  • MyCompany.MyProject.Infrastructure

  • MyCompany.MyProject.Abstract

Your main MVC project would then have a reference to your Abstract and Infrastructure projects. Your Infrastructure project would have a reference to the Abstract and instance specific projects like the Business and DAL projects. Within Infrastructure project you wire up the dependencies.

You'll have to setup a mechanism for your MVC project to bootstrap your IoC in the Infrastructure assembly. You can do that in your global.asax or as an App_Start method and call a Registration class within your Infrastructure assembly.

We use StructureMap, but the concept is the same. Here's some sample code.

In your MVC App, create a App_Start method to setup the DI.

public static class StructuremapMvc
{
    public static void Start()
    {

        // Create new Structuremap Controller factory so Structure map can resolve the parameter dependencies.
        ControllerBuilder.Current.SetControllerFactory(new StructuremapControllerFactory());

        IContainer container = IoC.Initialize();

        DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));

        GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
    }
}

In your Infrastructure assembly, wire up the dependencies.

public static class IoC
{
    public static IContainer Initialize()
    {
        ObjectFactory.Initialize(x =>
                    {
                        x.Scan(scan =>
                                {
                                    scan.TheCallingAssembly();
                                    scan.WithDefaultConventions();
                                });
                        x.For<IRepositoryNum1>().Use<Num1Repository>();
                        x.For<IRepositoryNum2>().Use<Num2Repository>();
                        x.For<IRepositoryNum3>().Use<Num3Repository>();
                    });

        return ObjectFactory.Container;
    }
}
like image 36
dblood Avatar answered Oct 08 '22 14:10

dblood