Search code examples
c#.net-assemblyautofac

Register different assembly types in autofac container in Asp.net


I have 3 tier architecture application. my Data Access is like below:

ICategoryRepository.cs

public interface ICategoryRepository
{
    void Add(Category category);
}

CategoryRepository.cs

internal class CategoryRepository : ICategoryRepository
{
    void ICategoryRepository.Add(Category category)
    {
        // Dbcontext goes here
    }
}

And I have a Autofac model to register the above classes in autofac container is:

public class RepositoryModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var assembly = System.Reflection.Assembly.GetExecutingAssembly();
        builder.RegisterAssemblyTypes(assembly)
               .Where(t => t.Name.EndsWith("Repository"))
               .AsImplementedInterfaces();
        base.Load(builder);
    }
}

And I have a service layer as below: ICategoryService.cs

public interface ICategoryService
{
  void Add(Category category);
}

CategoryService.cs

internal class CategoryService : ICategoryService
{
    private ICategoryRepository _categoryRepository;
    public CategoryService(ICategoryRepository categoryRepository)
    { 
        _categoryRespoitory = categoryRepository;
    }
    void ICategoryService.Add(Category category)
    {
        _categoryRepository.Add(category);
    }
}

Similarly, I have a module to register the above class in container as,

public class ServiceModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var assembly = System.Reflection.Assembly.GetExecutingAssembly();

        builder.RegisterAssemblyTypes(assembly)
               .Where(t => t.Name.EndsWith("Service"))
               .AsImplementedInterfaces()
               .InstancePerLifetimeScope();                        
    }
}

And in my Web, Global.asax.cs:

 public class Global : System.Web.HttpApplication, IContainerProviderAccessor
 {
     static IContainerProvider _containerProvider;

     public IContainerProvider ContainerProvider
     {
         get { return _containerProvider; }
     }

    void Application_Start(object sender, EventArgs e)
    {
        var builder = new ContainerBuilder();
        var assembly = System.Reflection.Assembly.GetExecutingAssembly();

        _containerProvider = new ContainerProvider(builder.Build());
    }
}

Here my question is, how can I call the service and DataAccess module from the web.

I don't have the data access reference in my web, but I have reference of service module in my web


Solution

  • You can use the RegisterAssemblyModules method

    void Application_Start(object sender, EventArgs e)
    {
        var builder = new ContainerBuilder();
    
        IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies();
        if (HostingEnvironment.InClientBuildManager)
        {
            assemblies = assemblies.Union(BuildManager.GetReferencedAssemblies()
                                                      .Cast<Assembly>())
                                   .Distinct();
        }
    
        builder.RegisterAssemblyModules(assemblies);
    
        _containerProvider = new ContainerProvider(builder.Build());
    }
    

    In order to let this code works, all your assemblies should be available on the bin folder.

    I use BuildManager.GetReferencedAssemblies() to avoid issue after ASP.net recycling process. See IIS Hosted Web Application on autofac documentation for more explanation.