前言 前面學習了autofac這個依賴註入組件,本來是打算寫在一起的,因為這個組件沒打算像autofac一樣詳細的寫,只是寫下以前自己鼓搗玩搭建框架然後使用的一個依賴註入組件,並且也是進行了封裝使用。不打算作為學習知識,僅作為使用封裝記錄的。 沒想autofac寫著寫著篇幅有點長,就單獨當作一個封裝 ...
前言
前面學習了autofac這個依賴註入組件,本來是打算寫在一起的,因為這個組件沒打算像autofac一樣詳細的寫,只是寫下以前自己鼓搗玩搭建框架然後使用的一個依賴註入組件,並且也是進行了封裝使用。不打算作為學習知識,僅作為使用封裝記錄的。
沒想autofac寫著寫著篇幅有點長,就單獨當作一個封裝類記錄一下吧。技術就和東西差不多長時間不使用就容易忘記。
上一篇autofac地址:【AutoFac】依賴註入和控制反轉的使用
Unity
引用dll
別的不說引用還是要簡單說一下的,在使用前要引用dll:
類文件結構
我這裡是把Unity組件和項目業務進行了分層所有我這個組件相當於在一個獨立的項目中,單獨的封裝到了IOC文件夾下創建,這裡不介紹整個解決方案了只對這個介紹下,大致的結構如下:
IOC封裝類
這個是主要類,容器的註入和獲取容器裡面的類相當於Unity的入口調用和請求都通過他,這個封裝有一個好處就是統一調用(廢話)。
/// <summary>
/// 依賴註入之區域註入方式
/// 沒有寫入到配置文件可傳參註入
/// </summary>
public class Ioc
{
private static readonly UnityContainer _container;
static Ioc()
{
_container = new UnityContainer();
}
public static void RegisterInheritedTypes(Assembly assembly, Type baseType)
{
_container.RegisterInheritedTypes(assembly, baseType);
}
public static void Register<TInterface, TImplementation>() where TImplementation : TInterface
{
_container.RegisterType<TInterface, TImplementation>();
}
public static T Get<T>()
{
return _container.Resolve<T>();
}
}
Unity擴展註冊
然後有一個Unity擴展註冊方法:
public static class UnityContainerExtensions
{
/// <summary>
/// Unity擴展註冊方法
/// </summary>
/// <param name="container"></param>
/// <param name="assembly"></param>
/// <param name="baseType"></param>
public static void RegisterInheritedTypes(this IUnityContainer container, Assembly assembly, Type baseType)
{
var allTypes = assembly.GetTypes();
var baseInterfaces = baseType.GetInterfaces();
foreach (var type in allTypes)
{
if (type.BaseType != null && type.BaseType.GenericEq(baseType))
{
var typeInterface = type.GetInterfaces().FirstOrDefault(x => !baseInterfaces.Any(bi => bi.GenericEq(x)));
if (typeInterface == null)
{
continue;
}
container.RegisterType(typeInterface, type);
}
}
}
}
這個很關鍵哦,這裡再說下我這裡其實不是每個類都要寫一遍註冊,而是所有業務類繼承於一個底層抽象類ServiceBase。然後傳入程式集和類型,就會把當前程式集下的所有這個類型註冊進去。
例如我有UserServer和UserServerTwo兩個業務類,我讓他都繼承ServiceBase抽象類,當然他們仍然要實現自己的服務介面的就拿UserServer舉例吧:
這樣我到時候使用只需要註冊一遍就把這兩個服務同時註入了。什麼好處在哪裡,第一註冊代碼寫少了,第二實現區域化分類。
註冊使用
使用根據mvc的控制器區域進行單獨註冊即可:
public override void RegisterArea(AreaRegistrationContext context)
{
//註冊使用代碼,先註冊後使用
Ioc.RegisterInheritedTypes(typeof(Server_Areas.Admin.IUserServer).Assembly, typeof(ServiceBase));
context.MapRoute(
"AdminAreas_default",
"AdminAreas/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "LayerFrame.Areas." + this.AreaName + ".Controllers" }
);
}
然後在該區域控制器使用:
public ActionResult Index()
{
//測試日誌
LogHelp.WriteFile("deBug", "這是日誌輸出哦");
//數據操作
var service = Ioc.Get<Server_Areas.Admin.IUserServer>();
//添加數據
UserInfor user = new UserInfor();
user.userAccount = "test001";
user.userPwd = "123456";
user.userPhone = "0530123456";
user.userRealName = "真實姓名";
user.userSex = 0;
user.userPhone = "0530123456";
user.userRemark = "備註內容";
user.addTime = DateTime.Now;
int count = service.UserAdd(user);
var data= service.GetData();
ViewBag.data = service.GetData();
return View();
}
Unity配置文件註入:
每次註入服務類是很麻煩的,比如修改了增加了,總不能一直去修改代碼吧,總是不好的,所以我們也可以寫到配置文件統一管理,比較方便(其實我上面封裝的也很方便了)。這個比上面好的是在於不用進行區域註冊了。全部統一註冊了。
UnityFactory類:
這裡我又一個地方是使用了以前的一篇【Config】類庫讀取自己的配置文件,配置文件的擴展,所以我是單獨在IOC文件夾下創建了對應的web.config文件,如果寫在項目跟web.config文件把註釋那句話取消即可。
public class UnityFactory
{
private static IUnityContainer _iUnityContainer = null;
private UnityFactory()
{
}
static UnityFactory()
{
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "IOC\\Unity.Config");
Configuration configuration = LibConfig.InitConfig("IOC\\Unity");
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
// UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
_iUnityContainer = new UnityContainer();
try
{
section.Configure(_iUnityContainer, "MyContainer");
}
catch (Exception e)
{
throw;
}
}
public static IUnityContainer GetContainerInstance()
{
return _iUnityContainer;
}
public static T GetServer<T>()
{
try
{
return _iUnityContainer.Resolve<T>();
}
catch (Exception e)
{
throw;
}
}
}
使用就特別簡單啦:
public ActionResult Test() {
try
{
var service = UnityFactory.GetServer<Server_Areas.Admin.UserServer>();
var data = service.GetData();
}
catch (Exception e)
{
}
return View();
}