zoukankan      html  css  js  c++  java
  • .Net Core 通过依赖注入和动态加载程序集实现宿主程序和接口实现类库完全解构

    网上很多.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:Userspesusource
    eposDynamicLoadDependencyInjectionConsoleAppClassLibrary1inDebug
    etcoreapp2.0ClassLibrary1.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:Userspesusource
    eposDynamicLoadDependencyInjectionConsoleAppClassLibrary1inDebug
    etcoreapp2.0ClassLibrary1.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();
            }
        }
    }

    输出:


    这有什么用呢?

  • 相关阅读:
    [LeetCode] Rotate Image
    [置顶] (奇迹冬瓜)坦克大战[MFC框架]
    spinner自定义,效果如腾讯QQ账号选择时候的下拉列表
    sqlmap dvwa SQL Injection使用小记
    Activex打包于发布完整版---微软证书制作
    假设web应用的文档根目录为MyApp,那么可以从哪里找到database.jar文件。
    无状态会话Bean、有状态会话Bean、CMP与BMP中,哪一种Bean不需要自己书写连接数据库的代码?
    EJB的优点有哪些?(选择2项)
    对触发器的认识;
    消耗资源的SQL的定位方法;
  • 原文地址:https://www.cnblogs.com/xiaozhuang/p/8862885.html
Copyright © 2011-2022 走看看