在MVC中使用Unity

  使用Unity,本例子,不包括使用web.config配置,直接代碼中使用。

1.建立BootStrapper類,負責處理Unity使用中的所有功能。

1.1引用 Microsoft.Practices.Unity 命名空間。

1.2創建IUnityContainer _current實體。

1.3註冊要使用的類,在本例子中,會自動註冊Controller類,利用反射技術。

代碼如下:

View Code
    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 能根據這個生存期處理實體。

這個生存期,表示在一個請求中,用一個實體,不需要重新初始化。

代碼如下:

View Code
  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 。

代碼如下:

View Code
    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中使用如下代碼:

View Code
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中,創建各個實體。然後你在代碼中直接使用就可以了。





posted @ 2012-03-07 14:21  無限遐想  阅读(3172)  评论(1编辑  收藏  举报