Unity: Injecting Multiple Registered PerResolveLifetimeManager Types

I use repositories that use a unit of work template:

public BaseRepository(IUnitOfWork unitOfWork, IEntityFactory factory) { ... }

Previously, I only needed one instance of IUnitOfWork introduced in the repository (using Unity), as shown below:

// Unit of work for the UserDbContext
container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor(new UserDbContext()));

container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<ITokenRepository, TokenRepository>();

Now I need to enter a different repository, but this repository should use a different instance IUnitOfWork:

// Unit of work for the OrderDbContext
container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor(new OrderDbContext()));

container.RegisterType<IOrderRepository, OrderRepository>();

How can I use Unity to explain, specify which IUnitOfWork will be introduced into any repository?

EDIT:

Using Daniel JG's answer, I have the following code:

container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor(new UserDbContext()));
container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>("OrderDbContext", new PerResolveLifetimeManager(), new InjectionConstructor(new OrderDbContext()));

container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<ITokenRepository, TokenRepository>();

container.RegisterType<IOrderRepository, OrderRepository>(
    new InjectionConstructor(
        new ResolvedParameter<IUnitOfWork>("OrderDbContext"),
        new ResolvedParameter<IEntityFactory<Order, int, OrderTbl>>()
    )
);

But the following exception occurs:

[ResolutionFailedException: , = "WebTest.Controllers.TestController", name = "(none)". : . : InvalidOperationException - IUnitOfWork .

UserRepository:

public class UserRepository : EntityFrameworkRepository<User, UserTbl>, IUserRepository
{
    public UserRepository(IUnitOfWork unitOfWork, IEntityFactory<User, UserTbl> factory)
        : base(unitOfWork, factory)
    { }
}

-. :

container.RegisterType<IEntityFactory<User, int, UserTbl>, UserFactory>();

EntityFrameworkUnitOfWork:

public class EntityFrameworkUnitOfWork : IUnitOfWork
{
    public EntityFrameworkUnitOfWork(DbContext context)
    {
        Context = context;
    }

    ...
}
+4
1

named registration > , IUnitOfWork.

Unity ( ) , . , IUnitOfWork . :

container.RegisterType<IUnitOfWork, UnitOfWork>(new PerResolveLifetimeManager(), 
                                                new InjectionConstructor(new UserDbContext()));

container.RegisterType<IUnitOfWork, UnitOfWork>("OrderUow", 
                                                new PerResolveLifetimeManager(), 
                                                new InjectionConstructor(new OrderDbContext()));

, IUnitOfWork , container.Resolve<IUnitOfWork>, , UserDbContext. - container.Resolve<IUnitOfWork>("OrderUow"), , OrderDbContext. ( , , )

, IUnitOfWork. ResolvedParameter, . (. SO)

, :

container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<ITokenRepository, TokenRepository>();
container.RegisterType<IOrderRepository, OrderRepository>(new InjectionConstructor(
                                       new ResolvedParameter<IUnitOfWork>("OrderUow"),
                                       //additional dependencies in the OrderRepository constructor, resolved using default Unity registrations
                                       new ResolvedParameter<IEntityFactory<Order,OrderTbl>>()));

, OrderRepository , Unity , IUnitOfWork , .

, :

public FooClass(IOrderRepository orderRepository, IUserRepository userRepository, ITokenRepository tokenRepository)
{
    ...
}
  • userRepository tokenRepository IUnitOfWork, UserDbContext.

  • orderRepository IUnitOfWork, OrderDbContext.

Edit

new InjectionConstructor , . IUnitOfWork IEntityFactory<T1, T2> . IOrderRepository , IEntityFactory<Order,OrderTbl> ( UserRepository, IEntityFactory<User, UserTbl>).

ResolvedParameter<T> typeOf(T). , InjectionConstructor , .

  • ,

    public UserRepository(IUnitOfWork unitOfWork, IEntityFactory<User, UserTbl> factory)
        : base(unitOfWork, factory)
    { }
    
  • InjectionConstructor :

    container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor(
                     //Let assume the Uow was registered as a named registration                   
                     new ResolvedParameter<IUnitOfWork>("UserUow"),
                     //provide information about additional parameters in the constructor
                     new ResolvedParameter<IEntityFactory<User,UserTbl>>()));
    
    container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor(
                     //Let assume the Uow was registered as a named registration                   
                     new ResolvedParameter<IUnitOfWork>("UserUow"),
                     //provide information about additional parameters in the constructor
                     typeof(<IEntityFactory<User,UserTbl>>)));
    

, UnitOfWork , InjectionConstructor , UnitOfWork .

2 -

:

public class DbContext
{
    public string Name { get; set; }
}

public interface IUnitOfWork
{
    DbContext DbContext { get; }
}    

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _dbContext;
    public UnitOfWork(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public DbContext DbContext { get { return _dbContext; } }
}

public interface IOrderRepository
{
    IUnitOfWork UnitOfWork { get;}
}

public class BaseRepository
{
    private readonly IUnitOfWork _uow;
    public BaseRepository(IUnitOfWork uow)
    {
        _uow = uow;
    }

    public IUnitOfWork UnitOfWork { get { return _uow; } }
}

public class OrderRepository : BaseRepository, IOrderRepository
{
    private IFooAdditionalDependency _foo;
    public OrderRepository(IUnitOfWork uow, IFooAdditionalDependency foo)
        : base(uow)
    {
        _foo = foo;
    }
}

public interface IFooAdditionalDependency { }
public class FooAdditionalDependency : IFooAdditionalDependency
{
}

public interface IUserRepository
{
    IUnitOfWork UnitOfWork { get; }
}

public class UserRepository : BaseRepository, IUserRepository
{
    public UserRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}



public interface ITokenRepository
{
    IUnitOfWork UnitOfWork { get; }
}

public class TokenRepository : BaseRepository, ITokenRepository
{
    public TokenRepository(IUnitOfWork uow)
        : base(uow)
    {
    }

}

Unity :

container.RegisterType<IUnitOfWork, UnitOfWork>(new PerResolveLifetimeManager(), 
                                    new InjectionConstructor(new DbContext{Name = "UserDB"}));
container.RegisterType<IUnitOfWork, UnitOfWork>("OrderDbContext", 
                                    new PerResolveLifetimeManager(),
                                    new InjectionConstructor(new DbContext { Name = "OrderDB" }));

container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<ITokenRepository, TokenRepository>();
container.RegisterType<IOrderRepository, OrderRepository>(new InjectionConstructor(
                                    new ResolvedParameter<IUnitOfWork>("OrderDbContext"),                                                                
                                    typeof(IFooAdditionalDependency)));

container.RegisterType<IFooAdditionalDependency, FooAdditionalDependency>();

-, :

public class HomeController : Controller
{
    public HomeController(IOrderRepository orderRepository, IUserRepository userRepository, ITokenRepository tokenRepository)
    {
        Debug.WriteLine("Order repository context: {0}, User repository context:{1}", orderRepository.UnitOfWork.DbContext.Name, userRepository.UnitOfWork.DbContext.Name);
        Debug.WriteLine("Order repository context: {0}, User repository context:{1}", orderRepository.UnitOfWork.DbContext.GetType().Name, userRepository.UnitOfWork.DbContext.GetType().Name);
        Debug.Assert(orderRepository.UnitOfWork != userRepository.UnitOfWork);
        Debug.Assert(userRepository.UnitOfWork == tokenRepository.UnitOfWork);
    }

    public ActionResult Index()
    {
        return View();
    }
}
+9

Source: https://habr.com/ru/post/1524489/


All Articles