简体   繁体   中英

Register multiple dbcontext using autofac where builder is not available to resolve the classes after registration

I have the following scenario, dependency injection happen outside of the class definitions given below, hence I don't have access to the builder object inside the classes. Problem is DbContext is mapped to two classes because I have two different databases I need to work with. In Order to create a SomeClass, need to instantiate MyRepository and MyOtherRepository, but to do that need 2 different DbContexts. That's where things fail as Autofac only takes the last mapping where the DbContext is mapped to MyOtherContext. Any help to resolve this problem is really appreciated, Thank you! Please let me know if more info is needed.

public class DependencyResolver : IDependencyResolver
{
   builder.RegisterType<MyContext>().As<DbContext>().InstancePerLifetimeScope();

  builder.RegisterType<MyOtherContext>().As<DbContext>().InstancePerLifetimeScope();

  builder.RegisterType<RepositoryManager.MyRepository>().As<Types.Repository.IMyRepository>().InstancePerDependency();

  builder.RegisterType<RepositoryManager.MyOtherRepository>().As<Types.Repository.IMyOtherRepository>().InstancePerDependency();
}

Class Definitions below

public class SomeClass
{
  public SomeClass(IMyRepository myRepository, IMyOtherRepository myOtherRepository)    
  {
      // Code
  }

}

public class MyContext : DbContext
{
   // Code
}

public class MyOtherContext : DbContext
{
   // Code
}

public class MyRepository : IRepository
{
    public MyRepository (DbContext context) : base(context)
    {
        // Code
    }
}

public class MyOtherRepository : IRepository
{
    public MyOtherRepository (DbContext context) : base(context)
    {
        // Code
    }
}

Try this answer . Basically you are looking for Autofac's Named and Keyed Services feature. I prefer resolving with attributes approach

So if you register contexts like that:

var builder = new ContainerBuilder();                
        builder
            .RegisterType<MyContext>()
            .As<DbContext>()
            .WithMetadata("EFContext", "My");
        builder
            .RegisterType<MyRepository>()
            .AsImplementedInterfaces();

        builder
            .RegisterType<MyOtherContext>()
            .As<DbContext>()
            .WithMetadata("EFContext", "Other");
        builder
            .RegisterType<MyOtherRepository>()
            .AsImplementedInterfaces();

you should be able to use them with (not strongly typed) metadata like that:

public class SomeClass
{
    private readonly IMyRepository _myRepository;
    private readonly IMyOtherRepository _myOtherRepository;

    public SomeClass(IMyRepository myRepository, IMyOtherRepository myOtherRepository)
    {
        _myRepository = myRepository;
        _myOtherRepository = myOtherRepository;
    }

    public string SayHello()
    {
        return $"Hello from {_myRepository.ContextName()}  and {_myOtherRepository.ContextName()}";
    }
}

public interface IMyOtherRepository
{
    string ContextName();
}

public interface IMyRepository
{
    string ContextName();
}

public class MyContext : DbContext
{
    // Code
}

public class MyOtherContext : DbContext
{
    // Code
}

public class MyRepository : IMyRepository
{
    private readonly IEnumerable<Meta<DbContext>> _context;

    public MyRepository(IEnumerable<Meta<DbContext>> context)
    {
        _context = context;
        // Code
    }

    public string ContextName() => _context.First(x => x.Metadata["EFContext"].Equals("My")).Value.GetType().Name;
}

public class MyOtherRepository : IMyOtherRepository
{
    private readonly IEnumerable<Meta<DbContext>> _context;

    public MyOtherRepository(IEnumerable<Meta<DbContext>> context)
    {
        this._context = context;
        // Code
    }

    public string ContextName() => _context.First(x => x.Metadata["EFContext"].Equals("Other")).Value.GetType().Name;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM