- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用使用工作单元模式的存储库:
public BaseRepository(IUnitOfWork unitOfWork, IEntityFactory factory) { ... }
以前我只需要将一个 IUnitOfWork 实例注入(inject)到存储库中(使用 Unity),如下所示:
// Unit of work for the UserDbContext
container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor(new UserDbContext()));
container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<ITokenRepository, TokenRepository>();
现在我需要引入另一个存储库,但是这个存储库需要使用不同的IUnitOfWork
实例:
// Unit of work for the OrderDbContext
container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor(new OrderDbContext()));
container.RegisterType<IOrderRepository, OrderRepository>();
我如何使用 Unity 明确指定将哪个 IUnitOfWork 注入(inject)哪个存储库?
编辑:
使用 Daniel J.G 的回答,我有以下代码:
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>>()
)
);
但是抛出以下异常:
[ResolutionFailedException: Resolution of the dependency failed, type = "WebTest.Controllers.TestController", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type IUnitOfWork does not have an accessible constructor.
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;
}
...
}
最佳答案
您可以使用 named registrations所以你可以注册并解析 IUnitOfWork
的不同flavours .
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 的实例。 (当你想使用命名注册时,你总是被迫解析传递名称的类型)
唯一剩下的就是为您的存储库正确连接注入(inject)参数,以便它们获得正确的 IUnitOfWork
实例。您可以通过配置 ResolvedParameter
来做到这一点,它允许您为任何依赖项指定命名注册。 (参见 this SO question)
这样,连接您的存储库的代码如下:
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
上下文。
编辑
使用 new InjectionConstructor
时您需要考虑要使用的构造函数的所有参数。对于您的存储库,您有 IUnitOfWork
和 IEntityFactory<T1, T2>
作为构造函数中的依赖项。我更新了IOrderRepository
的注册上面有一个依赖项,我猜是 IEntityFactory<Order,OrderTbl>
类型的(对于类型为 IEntityFactory<User, UserTbl>
的 UserRepository)。
要在构造函数中添加额外的依赖项,请添加更多 ResolvedParameter<T>
或者只是 typeOf(T)
.请注意 InjectionConstructor
中参数的顺序需要匹配您正在注册的类型的构造函数中的参数顺序。
换句话说,如果你有一个像
这样的构造函数public UserRepository(IUnitOfWork unitOfWork, IEntityFactory<User, UserTbl> factory)
: base(unitOfWork, factory)
{ }
您可以通过以下两种方式之一添加 InjectionConstructor:
container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor(
//Let's 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's 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 注册保留为默认注册,从而避免您在使用默认 UnitOfWork 的存储库上使用 InjectionConstructor。
编辑 2 - 示例代码
虚拟接口(interface)和实现:
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>();
需要存储库的虚拟 Controller :
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();
}
}
关于c# - 统一: Injection of multiple PerResolveLifetimeManager registered types,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21455981/
我正在更新a boilerplate中使用的babel包,从 babel-core、babel-register 等到@babel/core、@babel/register > 等 问题:在 npm
为了在 Babel 中进行运行时转换,您需要 require 并使用 babel-core/register。我不知道 register 在这个意义上意味着什么,即实际的定义。 The page is
我们可以使用“babel-register”即时转换源代码 https://babeljs.io/docs/usage/require/ 但我无法验证要使用哪一个: require('babel-co
我有一个用 RAL 建模的大寄存器映射,我想随机化一些寄存器。如果我想单独限制寄存器,那么这很简单: reg_model.register_a.randomize() with {value > 5;
我正在尝试制作一个使用 django 内置用户模型的简单应用程序。我已经创建了一个注册页面,但是当我运行服务器时,我在索引页面上收到此错误。这是我正在使用的代码: 注册.html {% extend
我正在尝试制作一个使用 django 内置用户模型的简单应用程序。我已经创建了一个注册页面,但是当我运行服务器时,我在索引页面上收到此错误。这是我正在使用的代码: 注册.html {% extend
在下面的应用程序中,我尝试将 id 动态添加到生成的项目中。我的代码工作正常,但是当我在其中添加以下两行注释时。它抛出错误 Uncaught Ext.AbstractManager.register(
当我尝试运行 SignUpFragmentTest 类时,出现错误“未注册检测!必须在注册检测下运行”。我认为当我使用@Rule 时会抛出错误。 import android.support.test
到目前为止,我目前的理解是:movq %rdi, %rax 将值从寄存器 %rdi 移动到寄存器 %rax 和movq (%rdi), %rax 会将内存中的值从(%rdi) 移动到寄存器%rax 但
我做了一个common view,所有页面都需要这个view。所以无论我需要什么,我都将这个 View 称为 xtype 。在这个公共(public) View 中,有一些组件由 id 值定义。 根据
app.get("/register", function(req, res) { res.render("register"); }); app.get("register", function(r
我目前正在开发我的个人网站 和我的网站的一部分,我有偏见的公关,以避免重复的代码... 这个 View 我有一个dojox.grid.datagrid ... 我可以在同一页面中两次调用此 View
调试版本对我来说工作正常。当我选择Active Build Variant = release,并尝试运行Build-> Generate Bundle(s)/ APK(s)-> Build APK时
我创建了一个异步函数如下: let createUserWrapper = async function(user){ await Log.createUser(use
我在 Dojo 的内容 Pane 中遇到问题,它出现一秒钟,然后内容消失。我收到以下错误: Uncaught ReferenceError: dijit is not defined index.p
我正在尝试在前端使用 React 创建一个注册表单,并在后端使用 Typescript 创建 Express 和 MongoDB atlas。当我单击提交按钮时,没有任何反应,但是当我使用 Postm
我已经使用 graph ql(具有非常基本的模式)创建了一个 Node js 项目,但是当我在为 graphql 和 graphiql 注册插件后尝试启动服务器时,我收到注册丢失错误。下面是我的代码
我的计算机体系结构书籍解释说 "Since writes to the register file are edge-triggered, our design can legally read an
我有一个 Google Pub/Sub 项目并创建了一个主题和一个简单的订阅。 但是,在指定用于推送的 URL 时,我不断收到以下错误。我已经完成了站点验证过程并在 API 和服务中注册了域,如 ht
您好,我在再次选择 DOJO 中的下拉菜单时遇到错误 function onReportTypesSelect() { if(
我是一名优秀的程序员,十分优秀!