Viv*_*ndi 1 c# dependency-injection inversion-of-control .net-core
.NET Core中是否有一种方法可以注册通用接口,并使其解析与某个实现相匹配的类.
例如,我有以下界面:
public interface IMapper<TFrom, TTo>
{
}
Run Code Online (Sandbox Code Playgroud)
我还有一个抽象类:
public abstract class Mapper<TFrom, TTo> : IMapper<TFrom, TTo>
{
protected Mapper()
{
// some generic stuff
}
public abstract TTo Map(TFrom);
}
Run Code Online (Sandbox Code Playgroud)
然后我可以创建一个这样的实现:
public class UserMapper : Mapper<Domain.User, Entity.User>
{
public override Entity.User Map(Domain.User from)
{
// do mapping
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法,使用默认的.NET Core DI进行注册IMapper<,>
,让它自动解析类?
所以,例如,如果我在代码中的某个地方执行此操作:
class SomeClass
{
public SomeClass(IMapper<Domain.User, Entity.User> mapper) {}
}
Run Code Online (Sandbox Code Playgroud)
它以某种方式知道它应该解决这个类UserMapper<Domain.User, Entity.User>
?
原因是手动注册每个映射器有点冗长,特定于实现.所以我希望Microsoft.DependencyInjection
能够以某种方式自动解决其实现.
您当前设计的唯一方法是使用Reflection:
Assembly assembly = typeof(UserMapper).Assembly;
foreach (var type in assembly.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract))
{
foreach (var i in type.GetInterfaces())
{
if (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapper<,>))
{
// NOTE: Due to a limitation of Microsoft.DependencyInjection we cannot
// register an open generic interface type without also having an open generic
// implementation type. So, we convert to a closed generic interface
// type to register.
var interfaceType = typeof(IMapper<,>).MakeGenericType(i.GetGenericArguments());
services.AddTransient(interfaceType, type);
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:您可以把它简单的创建一个扩展方法
IServiceCollection
与不同的重载AddTransient
,AddSingleton
等等.
如果更改设计,请使用非抽象泛型作为实现类型:
public class Mapper<TFrom, TTo> : IMapper<TFrom, TTo>
{
//...
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样注册:
services.AddTransient(typeof(IMapper<,>), typeof(Mapper<,>));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2508 次 |
最近记录: |