一、AutoFac介紹
Autofac是.NET裏IOC(Inversion of Control,控制反轉)容器的一種,同類的框架還有Spring.NET,Unity,Castle等。可以通過NuGet方式添加到項目中使用。
官方網站:http://autofac.org/
Autofac相對於其它的IoC框架優點:
- 它是C#語言聯繫很緊密,也就是說C#裏的很多編程方式都可以爲Autofac使用,例如可以用Lambda表達式註冊組件。
- 較低的學習曲線,學習它非常的簡單,只要你理解了IoC和DI的概念以及在何時需要使用它們。
- XML配置支持。
- 自動裝配。
- 與Asp.Net MVC集成。
- 微軟的Orchad開源程序使用的就是Autofac,從該源碼可以看出它的方便和強大。
二、什麼是控制反轉(IOC)、依賴注入(DI)
控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。Michael Mattson在1996年首次提出IoC的概念,IoC把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是鬆散耦合,而傳統應用程序都是由我們在類內部主動創建依賴對象,從而導致類與類之間高耦合。
依賴注入(Dependency Injection,簡稱DI),早在2004年,Martin Fowler就提出了“哪些方面的控制被反轉了?”這個問題。他總結出是依賴對象的獲得被反轉了,獲得依賴對象的過程由自身管理變爲了由IOC容器主動注入。於是,他給“控制反轉”取了一個更合適的名字叫做“依賴注入”。
三、AutoFac應用
1.添加引用
Autofac.dll,autofac框架核心類庫
Autofac.Integration.Mvc.dll,autofac框架對mvc的支持庫
Autofac.Configuration.dll,autofac框架獲取xml配置庫
2.創建autofac容器,注入對象
/// <summary>
/// 依賴注入接口
/// </summary>
public interface IinjectContainer
{
void RegisterType<T>();
T Resolve<T>();
}
public class AutoFacContainer : IinjectContainer
{
private ContainerBuilder builder;
private IContainer container;
public AutoFacContainer()
{
//創建autofac容器
builder = new ContainerBuilder();
// 獲取包含繼承了IService接口類的程序集註入
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly =>
assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(SQLTool.Service.IService))) != null).FirstOrDefault();
builder.RegisterAssemblyTypes(assemblies).Where(t => t.GetInterface(typeof(SQLTool.Service.IService).Name) != null).AsImplementedInterfaces().InstancePerLifetimeScope();
//注入xml文件<autofac>裏配置的對象,可以寫在web.config
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
//注入所有controller
builder.RegisterControllers(Assembly.GetExecutingAssembly());
//把容器裝入到微軟默認的依賴注入容器中
container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
public void RegisterType<T>()
{
builder.RegisterType<T>();
}
public T Resolve<T>()
{
return container.Resolve<T>();
}
}
3.IService及繼承IService接口項目代碼,web.config中autofac框架xml配置代碼
/// <summary>
/// IService空接口,autofac批量注入時使用
/// </summary>
public interface IService: IDisposable
{
}
/// <summary>
/// 實現IService接口的具體接口
/// </summary>
public interface IEOP_OrderInfoService : SQLTool.Service.IService
{
List<EOP_OrderInfo> GetOrderInfo();
}
/// <summary>
/// 實現接口的類
/// </summary>
public class EOP_OrderInfoService : ServiceBase, IEOP_OrderInfoService
{
/// <summary>
/// 實現方法
/// </summary>
/// <returns></returns>
public List<EOP_OrderInfo> GetOrderInfo()
{
//具體業務邏輯代碼,項目中用ef框架查詢的數據,測試的時候可以返回個字符串進行測試
var list = Context.EOP_OrderInfo.ToList();
return list;
}
}
xml配置文件代碼
<autofac>
<components>
<component type="HiMall_Test.IService.IEOP_OrderInfoService,EOP_OrderInfoService" service="HiMall_Test.SQLTool.Service.IService" />
</components>
</autofac>
4.創建對象容器
public class ObjectContainer
{
private static ObjectContainer current;
private static IinjectContainer container;
public ObjectContainer(IinjectContainer inversion)
{
container = inversion;
}
public static ObjectContainer Current
{
get
{
if (current == null)
{
RegisterAutoFac(container);
}
return current;
}
}
/// <summary>
/// 註冊autofac
/// </summary>
/// <param name="autofac"></param>
public static void RegisterAutoFac(IinjectContainer autofac)
{
container = autofac;
current = new ObjectContainer(container);
}
public T Resolve<T>()
{
return container.Resolve<T>();
}
}
5.在Global.asax中調用autofac框架
protected void Application_Start()
{
....
//調用autofac框架
ObjectContainer.RegisterAutoFac(new AutoFacContainer());
}
5.Controller中調用
public class HomeController : Controller
{
public IEOP_OrderInfoService _iEOP_OrderInfoService;
public HomeController()
{
}
public HomeController(IEOP_OrderInfoService iEOP_OrderInfoService)
{
this._iEOP_OrderInfoService = iEOP_OrderInfoService;
}
public ActionResult Index()
{
//方式1.構造器注入調用
var list = _iEOP_OrderInfoService.GetOrderInfo();
//方式2.使用容器Resolve調用
var list1 = ObjectContainer.Current.Resolve<IEOP_OrderInfoService>().GetOrderInfo();
if (list.Count > 0)
{
//log4net日誌
Core.Log.Debug("測試 : EOP_OrderInfo " + list.FirstOrDefault() == null ? "沒數據" : list.FirstOrDefault().ClientID);
}
else
{
//log4net日誌
Core.Log.Debug("測試 : EOP_OrderInfo 啥都沒有");
}
return View();
}
}
6.項目目錄結構圖