程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> CS.動態加載DLL.動態生成.運行代碼.BS.AutoFac管理實現類,dll.bs.autofac

CS.動態加載DLL.動態生成.運行代碼.BS.AutoFac管理實現類,dll.bs.autofac

編輯:C#入門知識

CS.動態加載DLL.動態生成.運行代碼.BS.AutoFac管理實現類,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會自動尋找實現類.在構造函數注入接口時注入實現類

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved