c# - 在 AutoFac 中使用带有参数的 lambda 表达式注册通用类型
问题描述
我正在尝试这样做,但是使用了一个通用类,例如:
public class BaseRepository<TEntity> : IBaseRepository<TEntity>, IDisposable
where TEntity : class, new()
{
public BaseRepository(IIndex<ContextKey, IDbContextBase> factory, ContextKey key)
{
Context = factory[key];
Set = Context.Set<TEntity>();
}
}
这样我就可以将ContextKey
密钥作为参数传递。
我正在尝试根据已传递给BaseRepository<>
类的 ctor 的密钥动态解析 dbcontext。
像这样注册它:
builder.Register((c, p) =>
new BaseRepository<>(p.Named<ContextKey>("key")))
.As<IBaseRepository<>>();
像这样解决:
var reader = scope.Resolve<IBaseRepository<ActionEntity>>(
new NamedParameter("key", ContextKey.Applications));
传递的密钥是:
public enum ContextKey
{
Pure, Phoebus, Applications, Legacy, None
}
并且该factory
参数内置在 Autofac 中 - 它由 Autofac 自动注入和处理。
解决方案
在IIndex<ContextKey, IDbContextBase> factory, ContextKey key
存储库构造函数中拥有看起来很像可以委托给组合根的实现问题。
我将首先简化存储库的构造函数以遵循显式依赖原则。
public class BaseRepository<TEntity> : IBaseRepository<TEntity>, IDisposable
where TEntity : class, new() {
//...
public BaseRepository(IDbContextBase context) {
Context = context;
Set = Context.Set<TEntity>();
}
//...
}
然后,Composition Root 将负责确保正确构建存储库。
ContextKey key = //known value
//...Assumes IIndex<ContextKey, IDbContextBase> factory is registered
builder
.RegisterGeneric(typeof(BaseRepository<>))
.As(typeof(IBaseRepository<>))
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IDbContextBase) && pi.Name == "context",
(pi, ctx) => {
var factory = ctx.Resolve<IIndex<ContextKey, IDbContextBase>>();
return factory[key];
})
);
//...
var container = builder.Build();
注意使用ResolvedParameter
动态获取要注入存储库的参数。
推荐阅读
- java - iText 7:此 pdf 文档可能无法正确显示 Firefox
- node.js - Node.js 服务器未正确提供文件
- c# - Entity Framework Core 首次查询与后续查询性能
- r - Shiny:增加 MathJax 的字体大小
- templates - Shopware 自定义选项卡在选择变体后导致错误
- powerquery - 如果 logic = true,则使用前一行的值,否则使用另一列
- django - Django 不创建迁移来为遗留外键字段创建索引
- reactjs - 需要帮助将此代码从类组件(React)转换为功能挂钩
- python-2.7 - Ansible:检查磁盘大小并根据其大小创建卷组
- django - 在生产中部署 Django 时使用 apache 工作人员的优缺点是什么?