zoukankan      html  css  js  c++  java
  • CS.动态加载DLL.动态生成.运行代码.BS.AutoFac管理实现类

           以英雄联盟为例.界面上经常有Load....xxxx.dll. 

                       一般都是加载子系统.比如装备系统.英雄系统等.

                                       在实际开发中很多项目非常庞大.都会分割成独立子解决方案开发.

                                              后期就需要加载回来.

                                                     一般都是利用代码动态加载.

                                                           ....这个时间博客园维护貌似不能上传图片.

                                                                        将就点看

     Father //母解决方案.登陆页面和Load.加载子解决方案Dll页面

    Father1//母解决方案下的类库有共通的父类.所有的子解决方案都会加载此类库

    Son//子解决方案.装备系统.英雄系统

    ------------------------------------

    思路是.Father解决方案加载所有的Son子解决方案.利用Father1解决方案产生关联

    Father1可能就是一个接口.Son实现.但是Son独立于Father成立新的解决方案

    Father1:

    public interface Class1
    {
    void run(string message);
    }

    Son:

    public class Class1:ClassLibrary1.Class1
    {
    public void run(string message)
    {
    Console.WriteLine(message);
    }
    }

    Father:

    var filepath = @"C:UsersAdministratorDesktopDEV_DLLConsoleApplication1ClassLibrary2inDebugClassLibrary2.dll";
    var ass = System.Reflection.Assembly.LoadFrom(filepath);
    foreach (var item in ass.GetTypes())
    {
    if (item.GetInterface("Class1")!=null)
    {
    var classlibrary = (ClassLibrary1.Class1)Activator.CreateInstance(item);
    classlibrary.run("hello");
    }
    
    }

    完成动态加载.因为是动态dll.经常会遇到需要动态编写代码并执行.

    比如 string a= "string b=‘1’";

    然后使b生效

    CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
    
    
    ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();
    
    
    CompilerParameters objCompilerParameters = new CompilerParameters();
    objCompilerParameters.ReferencedAssemblies.Add("System.dll");
    objCompilerParameters.GenerateExecutable = false;
    objCompilerParameters.GenerateInMemory = true;
    
    // 4.CompilerResults
    CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode());
    
    if (cr.Errors.HasErrors)
    {
    Console.WriteLine("编译错误:");
    foreach (CompilerError err in cr.Errors)
    {
    Console.WriteLine(err.ErrorText);
    }
    }
    else
    {
    // 通过反射,调用HelloWorld的实例
    Assembly objAssembly = cr.CompiledAssembly;
    object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
    MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
    
    Console.WriteLine(objMI.Invoke(objHelloWorld, null));
    }
    
     
    
    static string GenerateCode()
    {
    StringBuilder sb = new StringBuilder();
    sb.Append("using System;");
    sb.Append(Environment.NewLine);
    sb.Append("namespace DynamicCodeGenerate");
    sb.Append(Environment.NewLine);
    sb.Append("{");
    sb.Append(Environment.NewLine);
    sb.Append(" public class HelloWorld");
    sb.Append(Environment.NewLine);
    sb.Append(" {");
    sb.Append(Environment.NewLine);
    sb.Append(" public string OutPut()");
    sb.Append(Environment.NewLine);
    sb.Append(" {");
    sb.Append(Environment.NewLine);
    sb.Append(" return "Hello world!";");
    sb.Append(Environment.NewLine);
    sb.Append(" }");
    sb.Append(Environment.NewLine);
    sb.Append(" }");
    sb.Append(Environment.NewLine);
    sb.Append("}");
    
    string code = sb.ToString();
    Console.WriteLine(code);
    Console.WriteLine();
    
    return code;
    }

    //以上完成动态编写执行代码

    AutoFac是一款最轻量级最快的IOC框架.

              并被微软推荐.

                    依赖注入.依赖实现类注入容器

                            控制反转.在容器中分离实现类

                                  核心思想.面向接口编程而非实现类

                                       AutoFac有两种注入方式.一种是依赖注入.效果为一个接口对应一个实现类.手动注入

                                                    一种是依赖查询.利用IDependency接口完成实现类自动注入.

    //手动注入
    
    var builder = new ContainerBuilder();
    SetupResolveRules(builder);
    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
    
    private void SetupResolveRules(ContainerBuilder builder)
    {
    builder.RegisterType<GradeService1>().As<IGradeService1>();
    builder.RegisterType<GradeService>().As<IGradeService>();
    
    //显式类型注册
    }

    在Global.asax中创建IOC容器ContainerBuilder.

                   在构造函数中注入接口.

                         IOC会自动注入实现类

    public HomeController(IGradeService1 ser, IGradeService ser1)
    {
    Ser1 = ser;
    Ser = ser1;
    }
    
    public ActionResult Index()
    {
    var a=Ser.GetName();
    var a1 = Ser1.GetName();
    return View();
    }
    //自动注册
    
     
    
    AreaRegistration.RegisterAllAreas();
    
    var builder = RegisterService();
    
    DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
    
    //依赖IDependency接口自动注册
    
     
    
    public ContainerBuilder RegisterService()
    {
    var builder = new ContainerBuilder();
    
    var baseType = typeof(IDependency);
    var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
    var AllServices = assemblys
    .SelectMany(s => s.GetTypes())
    .Where(p => baseType.IsAssignableFrom(p) && p != baseType);
    
    builder.RegisterControllers(assemblys.ToArray());
    
    builder.RegisterAssemblyTypes(assemblys.ToArray())
    .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
    .AsImplementedInterfaces().InstancePerLifetimeScope();
    return builder;
    }

    //利用拉姆达推演类型寻找实现类

    //创建IDependency接口

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WebApplication1.Models
    {
    public interface IDependency
    {
    }
    }
    
     
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using WebApplication1.Models;
    
    namespace WebApplication1.Controllers
    {
    public interface IGradeService: IDependency
    {
    string GetName();
    
    }
    public interface IGradeService1:IDependency
    {
    string GetName();
    
    }
    }

    只要接口继承了IDependency.AutoFac会自动寻找实现类.在构造函数注入接口时注入实现类

  • 相关阅读:
    nodejs初期,搭建一个登陆注册功能,(原生的)
    关于vue如何创建一个自定义组件(这是项目中经常得用的)
    关于vue 使用watch方法,详解。
    怎样用Nodejs搭建一个服务器
    关于Promise的理解及运用
    Ado.NET SQLHelper(2)
    Ado.NET SQLHelper
    MS SQLSERVER 自增ID列竟然会重复
    SQL中Left Join 与Right Join 与 Inner Join 与 Full Join的区别
    thread.start和threadstart.invoke的区别
  • 原文地址:https://www.cnblogs.com/Gao1234/p/5950271.html
Copyright © 2011-2022 走看看