在MVC中使用Unity
使用Unity,本例子,不包括使用web.config配置,直接代碼中使用。
1.建立BootStrapper類,負責處理Unity使用中的所有功能。
1.1引用 Microsoft.Practices.Unity 命名空間。
1.2創建IUnityContainer _current實體。
1.3註冊要使用的類,在本例子中,會自動註冊Controller類,利用反射技術。
代碼如下:
public class BootStrapper
{
private static IUnityContainer _current;
private static readonly object Locker = new object();
private static IUnityContainer Current
{
get
{
if (_current == null)
{
lock (Locker)
{
if (_current == null)
{
_current = new UnityContainer();
}
}
}
return _current;
}
}
public static void RegisterDependency()
{
if (_current == null)
{
_current = Current;
}
#region 所有DLL路径
var dllPaths =
Directory.GetFiles(HttpContext.Current.Server.MapPath("~/bin"), "*.dll");
#endregion
#region 所有controllers类型
var typeListController =
dllPaths.Select(path =>
{
try
{
return Assembly.LoadFrom(path);
}
catch (Exception ex)
{
return null;
}
}).Where(a => a != null).Select(a =>
{
try
{
return a.GetTypes();
}
catch (Exception ex)
{
return null;
}
}).SelectMany(ts => ts).
Where(t => (t.BaseType != null) && (t.BaseType.Name == "BaseController"))
.ToList();
foreach (var item in typeListController)
{
_current.RegisterType(typeof(BaseController), item, item.Name);
}
#endregion
#region 接口註冊
_current.RegisterType<IUHDEntities, UHDEntities>(new HttpContextLifetimeManager<IUHDEntities>());
_current.RegisterType<IChoiceServers, ChoiceServers>();
_current.RegisterType<IFeedbackServers, FeedbackServers>();
_current.RegisterType<IDocumentServers, DocumentServers>();
_current.RegisterType<IAttachmentServers, AttachmentServers>();
_current.RegisterType<ISendWorkServers, SendWorkServers>();
_current.RegisterType<IUsersServers, UsersServers>();
_current.RegisterType<IWorkRecordServers, WorkRecordServers>();
_current.RegisterType<ICompanyServers, CompanyServers>();
_current.RegisterType<IDeptServers, DeptServers>();
_current.RegisterType<IFeedbackDetailsServers, FeedbackDetailsServers>();
_current.RegisterType<IUpFeedbackServers, UpFeedbackServers>();
#endregion
}
public static Controller GetSingleController(Type name)
{
return _current.Resolve<BaseController>(name.Name);
}
public static T GetSingleModels<T>()
{
return _current.Resolve<T>();
}
}
2.建立一個生存期的類HttpContextLifetimeManager,使得Unity 能根據這個生存期處理實體。
這個生存期,表示在一個請求中,用一個實體,不需要重新初始化。
代碼如下:
public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
public override object GetValue()
{
return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
}
public void Dispose()
{
RemoveValue();
}
}
3.我在代碼中這樣註冊實體的生存期
如下代碼:
_current.RegisterType<IUHDEntities, UHDEntities>(new HttpContextLifetimeManager<IUHDEntities>());
註冊了一個 數據庫連接的實體。也就是 此數據庫實體,再一個請求中,只使用這一個。
4.為了在MVC中使用,特別聲明一個繼承DefaultControllerFactory類的實體IoCControllerFactory 。
代碼如下:
public class IoCControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
return BootStrapper.GetSingleController(controllerType);
}
return base.GetControllerInstance(requestContext, controllerType);
}
}
5.在 Global.asax中的Application_Start事件中,添加如下代碼:
BootStrapper.RegisterDependency();
ControllerBuilder.Current.SetControllerFactory(new IoCControllerFactory());
6.這樣可以建立任何一個Controller,如AccountController,我在這裡Controller都繼承BaseController
BaseController繼承Controller,然後在AccountController中使用如下代碼:
public class AccountController : BaseController
{
private readonly IUsersServers _UsersServers;
private readonly IDeptServers _DeptServers;
public AccountController(IUsersServers _UsersServers, IDeptServers _DeptServers)
{
this._DeptServers = _DeptServers;
this._UsersServers = _UsersServers;
}
//
// GET: /Account/
public ActionResult LogOn()
{
if (Function.lstDept == null)
{
Function.lstDept = _DeptServers.GetDeptAll();
}
return View();
}
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (_UsersServers.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Feedback");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/LogOff
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return RedirectToAction("LogOn", "Account");
}
[HttpPost]
public ActionResult ChangePassword(string oldPass, string newPass, string ConfirmPassword)
{
string Right = "0";
if (Function.User.Passwd==oldPass)
{
// ChangePassword will throw an exception rather
// than return false in certain failure scenarios.
bool changePasswordSucceeded;
try
{
changePasswordSucceeded = _UsersServers.ChangePassword(Function.User.UserID, oldPass, newPass);
}
catch (Exception)
{
changePasswordSucceeded = false;
}
if (changePasswordSucceeded)
{
Right="1";
}
else
{
Right="0";
}
}
return Content(Right);
}
}
說明:
其中 private readonly IUsersServers _UsersServers;
private readonly IDeptServers _DeptServers;
是在Unity中註冊的接口。
只有你 一訪問 AccountController類:
public AccountController(IUsersServers _UsersServers, IDeptServers _DeptServers)
{
this._DeptServers = _DeptServers;
this._UsersServers = _UsersServers;
}
方法,會自動,通過Unity中,創建各個實體。然後你在代碼中直接使用就可以了。