views:

940

answers:

3

The examples I can find use a two layer architecture, where the controllers directly use the repository classes in the data access layer. See here or here.

Where would you register components from the data access layer if you have a service or business logic layer that uses those components? The data access layer should ideally not be referenced from the user interface layer, right? So Application_Start would not be the right place to do it.

What would be a better way?

Thank you!

A: 

For example:

public class CustomerService() {
  // Dependency, should be resolved
  public ICustomerRepository repository;

  public void DeleteCustomer(Customer c) {
    // Let's do some business logic, like clearing shopping cart or checking the balance.
    // OK to delete?
    repository.Delete(c);
  }
}

The controller uses the CustomerService to delete a customer when the form is submitted. It just instantiates the CustomerService and calls the DeleteCustomer method. How to use Autofac to make sure the depency of the CustomerService on a ICustomerRepository is resolved?

Of course, other application architectures are possible, and maybe this is not the best one, but it is the one from my question.

michielvoo
A: 

Here is an example that uses StructureMap. In the web application it references the data access layer.

See the code Commerce.Web/App/Bootstrapper.cs

ForRequestedType<ICatalogRepository>()
  .TheDefaultIsConcreteType<SqlCatalogRepository>();
michielvoo
+4  A: 

Something has to know about which implementations you want to use. There's typically 3 ways to accomplish this:

  1. at compile time which is what Autofac uses
  2. at runtime from predefined config file which Castle Windsor can do
  3. at runtime with a dyanamic configuartion

With Autofac you have a few choices

  1. Wire everything together in Application_Start
  2. Give the responsibility to another component which implements a factory pattern and registers the required components.

For #2 I would implement something like an IContainer interface so that your IoC framework is loosely coupled with your system. Then have your data access implemenations use that interface to registered the required components.

Todd Smith
OK, so in the first case (everything in Application_Start) is it a problem that the web application now has to have a direct reference to the data access layer assembly?
michielvoo
If having your Application_Start know about your data access layer is an issue you can always abstract your IoC implementation behind an interface and move it somewhere else. Then the decision of what DAL to register can be made oblivious to your web application.
Todd Smith
Unless your DAL is sitting behind a web service your web application is going to need access to your DAL assembly via the bin directory or GAC, no?
Todd Smith
You could at least "hide" each layers requirements into Autofac Modules. Then the module for a given layer will "know" about the types it needs, but the main app (Application_Start) will only need to know about which modules to load.
Peter Lillevold