从接口继承时自动实现依赖项注入



最近,我使用了ASP锅炉示例。它有一些类来实现依赖项注入,例如ITransientDependency

当一个类实现ITransientDependency接口时,它可以被注入构造函数,而无需在启动文件中进行任何配置。

我也想这么做,但不知道怎么做。请告诉我该怎么办,有图书馆可以支持还是有文档。

您可以通过反射来实现这一点,但这并非微不足道。

以下假设您已经设置了依赖项注入容器。

步骤1

首先,您需要从所有当前程序集中获取所有类型,但只能获取那些不是抽象或接口的类型(即可以创建的类型(:

var types = from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
where t.IsAssignableFrom(typeof(ITransientDependency))
&& !t.IsAbstract && !t.IsInterface
select t;

这将返回Type对象的列表,这些对象表示从所有当前加载的程序集中实现ITransientDependency的类。

步骤2

接下来,您需要将它们添加到依赖注入容器中。假设您使用的是Microsoft的IServiceCollection,那么您可以这样做(例如,在Startup类中的ConfigureServices方法中(:

foreach (var t in types)
{
services.AddTransient(t);
}

注意:这并不是真正的DI最佳实践。通常,您应该注入接口,而不是实现,并像这样添加每个接口:

services.AddTransient<ISomeDependency, SomeImpl>();
services.AddTransient<IAnotherDependency, AnotherImpl>();
// and so on

这有助于测试驱动的开发,因为您可以创建接口的模拟实现,但不能创建实现。

步骤3

最后,您现在可以通过构造函数将这些注入到类中:

public class SomeClass
{
public SomeClass(SomeDependency dep)
{
// do something
}
}

这样做需要小心,因为您可能会在运行时引入问题-例如,所有ITransientDependency实现的依赖项也需要添加到DI容器中,并且它们不能有任何其他依赖项(例如值类型(。

警告

第一步中使用的GetTypes()方法可能引发异常,因此需要处理该异常。我过去曾通过将其推广到一种扩展方法中来做到这一点:

internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}

最新更新