CS.动态加载DLL.动态生成.运行代码.BS.AutoFac管理实现类

Posted 高1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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会自动寻找实现类.在构造函数注入接口时注入实现类

 

以上是关于CS.动态加载DLL.动态生成.运行代码.BS.AutoFac管理实现类的主要内容,如果未能解决你的问题,请参考以下文章

C# 写一个动态加载DLL的程序 怎么写?

C#开发的OpenRA动态加载插件DLL里的类实现

C#开发的OpenRA动态加载插件DLL里的类实现

怎样将dll文件转换成cs文件

静态库 动态库 调用

[转载] 动态链接库dll的 静态加载 与 动态加载