作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要访问我的 IEntityTypeConfiguration 类中的一些 DI 服务,以便找到一些用户 session 信息并执行一些查询过滤。
我可以通过执行以下操作以“手动”方式实现这一目标......
// setup config to use injection (everything normal here)
public class MyEntityConfig: IEntityTypeConfiguration<MyEntity>
{
private readonly IService _service;
public MyEntityConfig(IService service)
{
IService = service;
}
public void Configure(EntityTypeBuilder<MyEntity> entity)
{
// do some stuff to entity here using injected _service
}
}
//use my normal DI (autofac) to inject into my context, then manually inject into config
public class MyContext: DbContext
{
private readonly IService _service;
public MyContext(DbContextOptions options, IService service) : base(options)
{
_service = service;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//this works no problem
modelBuilder.ApplyConfiguration(new MyEntityConfig(_service));
}
}
\\modelBuilder.ApplyConfiguration(new MyEntityConfig(_service));
modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyContext).Assembly);
最佳答案
所以这就是我在跟随@Cyril 的领导并调查源代码后想出的。我“借用”了现有的 ModelBuilder.ApplyConfigurationsFromAssembly() 方法并重新编写了一个新版本(作为模型构建器扩展),它可以采用服务参数列表。
/// <summary>
/// This extension was built from code ripped out of the EF source. I re-jigged it to find
/// both constructors that are empty (like normal) and also those that have services injection
/// in them and run the appropriate constructor for them and then run the config within them.
///
/// This allows us to write EF configs that have injected services in them.
/// </summary>
public static ModelBuilder ApplyConfigurationsFromAssemblyWithServiceInjection(this ModelBuilder modelBuilder, Assembly assembly, params object[] services)
{
// get the method 'ApplyConfiguration()' so we can invoke it against instances when we find them
var applyConfigurationMethod = typeof(ModelBuilder).GetMethods().Single(e => e.Name == "ApplyConfiguration" && e.ContainsGenericParameters &&
e.GetParameters().SingleOrDefault()?.ParameterType.GetGenericTypeDefinition() ==
typeof(IEntityTypeConfiguration<>));
// test to find IEntityTypeConfiguration<> classes
static bool IsEntityTypeConfiguration(Type i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>);
// find all appropriate classes, then create an instance and invoke the configure method on them
assembly.GetConstructableTypes()
.ToList()
.ForEach(t => t.GetInterfaces()
.Where(IsEntityTypeConfiguration)
.ToList()
.ForEach(i =>
{
{
var hasServiceConstructor = t.GetConstructor(services.Select(s => s.GetType()).ToArray()) != null;
var hasEmptyConstructor = t.GetConstructor(Type.EmptyTypes) != null;
if (hasServiceConstructor)
{
applyConfigurationMethod
.MakeGenericMethod(i.GenericTypeArguments[0])
.Invoke(modelBuilder, new[] { Activator.CreateInstance(t, services) });
Log.Information("Registering EF Config {type} with {count} injected services {services}", t.Name, services.Length, services);
}
else if (hasEmptyConstructor)
{
applyConfigurationMethod
.MakeGenericMethod(i.GenericTypeArguments[0])
.Invoke(modelBuilder, new[] { Activator.CreateInstance(t) });
Log.Information("Registering EF Config {type} without injected services", t.Name, services.Length);
}
}
})
);
return modelBuilder;
}
private static IEnumerable<TypeInfo> GetConstructableTypes(this Assembly assembly)
{
return assembly.GetLoadableDefinedTypes().Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition);
}
private static IEnumerable<TypeInfo> GetLoadableDefinedTypes(this Assembly assembly)
{
try
{
return assembly.DefinedTypes;
}
catch (ReflectionTypeLoadException ex)
{
return ex.Types.Where(t => t != null as Type).Select(IntrospectionExtensions.GetTypeInfo);
}
}
}
modelBuilder.ApplyConfigurationsFromAssemblyWithServiceInjection(typeof(MyContext).Assembly, myService, myOtherService);
关于c# - 使用 ApplyConfigurationsFromAssembly() 程序集扫描时访问 IEntityTypeConfiguration<T> 内的 DI 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58638358/
我需要访问我的 IEntityTypeConfiguration 类中的一些 DI 服务,以便找到一些用户 session 信息并执行一些查询过滤。 我可以通过执行以下操作以“手动”方式实现这一目标.
我是一名优秀的程序员,十分优秀!