徐州网站建设公司官网,个人网站要买多大的空间,海南住房建设厅网站,网站开发 培训 周末班依赖注入配置变形
随着业务的增长#xff0c;我们项目工作中的类型、服务越来越多#xff0c;而每一个服务的依赖注入关系都需要在入口文件通过Service.Add{}方法去进行注册#xff0c;这将是非常麻烦的#xff0c;入口文件需要频繁改动#xff0c;而且代码组织管理也会变…
依赖注入配置变形
随着业务的增长我们项目工作中的类型、服务越来越多而每一个服务的依赖注入关系都需要在入口文件通过Service.Add{}方法去进行注册这将是非常麻烦的入口文件需要频繁改动而且代码组织管理也会变得麻烦非常不优雅。
在许多框架中会对这种通过 Service.Add{xxx} 的方式在代码中显式注册依赖注入关系的方式进行变形有的可以通过配置文件进行注册 这里稍微简单介绍一下依赖注入默认注册的原理其实也就是通过放射的一些手段再加上一些约定好的规则而已。
约定 实现类要接口结尾 》Izen 接口 》实现类 MyServiceZen
这里稍微简单介绍一下依赖注入默认注册的原理其实也就是通过放射的一些手段再加上一些约定好的规则而已。
public interface ISingleton
{
}
public interface IScoped
{
}
public interface ITransient
{
}
》》定义一个扩展类 实现 IServiceCollection 的扩展方法
namespace Microsoft.Extensions.DependencyInjection
{public static class ServiceCollectionDependencyExtensions{public static IServiceCollection AddAutoInjectT(this IServiceCollection services){var register new ServiceRegister();register.AddAssembly(services, typeof(T).Assembly);return services;}}
}
》》》这个扩展方法中调用了注册器往容器中注入服务实现如下 public class ServiceRegister
{public void AddAssembly(IServiceCollection services, Assembly assembly){// 查找程序中的类型var types assembly.GetTypes().Where(t t ! null t.IsClass !t.IsAbstract !t.IsGenericType);// 遍历每一个类检查释放满足约定的规则foreach (var type in types){AddType(services, type);}}/// summary/// 添加当前类型的依赖注入关系/// /summary/// param nameservices/param/// param nametype/parampublic void AddType(IServiceCollection services, Type type){var lifetime GetLifetimeOrNull(type);if (lifetime null){return;var exposeServices ExposeService(type);foreach (var serviceType in exposeServices){var serviceDescriptor new ServiceDescriptor(serviceType, type, lifetime.Value);services.Add(serviceDescriptor);}}/// summary/// 根据标记接口确定生命周期如果没有添加标记接口的则不会被自动注册到容器/// /summary/// param nametype/param/// returns/returnspublic ServiceLifetime? GetLifetimeOrNull(Type type){if (typeof(ISingleton).IsAssignableFrom(type)){return ServiceLifetime.Singleton;}if(typeof(IScoped).IsAssignableFrom(type)){return ServiceLifetime.Scoped;}if(typeof(ITransient).IsAssignableFrom(type)){return ServiceLifetime.Transient;}return null;}/// summary/// 根据约定的规则查找当前类对于的服务类型/// 通过接口实现的方式查找当前类实现的接口如果一个接口名称去除了 I 之后与当前类的后半段一样/// 则当前类应该被注册为这个接口的服务。/// /summary/// param nametype/param/// returns/returnspublic IListType ExposeService(Type type){var serviceTypes new ListType();var interfaces type.GetInterfaces();foreach (var interfacesType in interfaces){var interfaceName interfacesType.Name;if (interfaceName.StartsWith(I)){interfaceName interfaceName.Substring(1);}if (type.Name.EndsWith(interfaceName)){serviceTypes.Add(interfacesType);}}return serviceTypes;}
}
整体的逻辑就是查找遍历程序集中的所有类型并通过判别类型是否实现之前定好的三个生命周期接口 从而确定类型是否需要自动注册到容器中如果需要再根据约定好的规则获取需要注册的服务类型并且构建服务描述器再将其添加到容器中。
之后在入口文件中这样使用 》builder.Services.AddAutoInject();