6
votes

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?

3
Using a repo doesn't mean you have to use DI - they solve two different problems.Nick Butler
I'd recommend reading up on "onion architecture", I think it's a good approach to project references. Because your UI and DataAccess layers will both be right on the outside, there shouldn't be any problem for them to reference each other.Charlino

3 Answers

4
votes

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).

3
votes

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;
    }
}
0
votes

You should use DI to inject the Domain/DAL interfaces into your constructors. This has a lot of upside including allowing you to moq your interfaces when you write your unit tests. You can use Autofac to handle the injection.