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:\Users\Administrator\Desktop\DEV_DLL\ConsoleApplication1\ClassLibrary2\bin\Debug\ClassLibrary2.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会自动寻找实现类.在构造函数注入接口时注入实现类