来源: .Net Core 通过依赖注入和动态加载程序集实现宿主程序和接口实现类库完全解构…_weixin_34128839的博客-CSDN博客
网上很多.Net Core依赖注入的例子代码,例如再宿主程序中要这样写:
services.AddTransient<Interface1, Class1>();
其中Interface1是接口,Class1是接口的实现类,一般我们会将接口项目和实现类项目分开成两个项目以实现解耦。
但这段代码却要求宿主程序要引用实现类项目,所以这里的解构实现的并不彻底,要完全解耦就是要实现宿主程序不引用实现类项目。
或者把注入的代码改成这样:
services.Add(new ServiceDescriptor(serviceType: typeof(Interface1), implementationType: Type.GetType("ClassLibrary1.Class1, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"), lifetime: ServiceLifetime.Transient));
其实这段代码也要求宿主类引用实现类库项目,不然运行会出错,只有采用动态加载程序集的方式才能实现宿主程序不引用实现类:
var myAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(@"C:\Users\pesu\source\repos\DynamicLoadDependencyInjectionConsoleApp\ClassLibrary1\bin\Debug\netcoreapp2.0\ClassLibrary1.dll");
上面代码将实现类库程序集动态加载到宿主程序,然后将注入的代码改成这样:
services.Add(new ServiceDescriptor(serviceType: typeof(Interface1), implementationType: myAssembly.GetType("ClassLibrary1.Class1"), lifetime: ServiceLifetime.Transient));
其中ClassLibrary1.Class1是Interface1的实现类,完整代码如下:
using InterfaceLibrary; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; using System.Runtime.Loader; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var myAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(@"C:\Users\pesu\source\repos\DynamicLoadDependencyInjectionConsoleApp\ClassLibrary1\bin\Debug\netcoreapp2.0\ClassLibrary1.dll"); IServiceCollection services = new ServiceCollection(); //注入 services.AddTransient<ILoggerFactory, LoggerFactory>(); services.Add(new ServiceDescriptor(serviceType: typeof(Interface1), implementationType: myAssembly.GetType("ClassLibrary1.Class1"), lifetime: ServiceLifetime.Transient)); //构建容器 IServiceProvider serviceProvider = services.BuildServiceProvider(); //解析 serviceProvider.GetService<ILoggerFactory>().AddConsole(LogLevel.Debug); var cls = serviceProvider.GetService<Interface1>(); cls.Say(); Console.ReadKey(); } } }
输出:
这有什么用呢?