我有一个ASP.NET MVC Web应用程序,它实现了一个自定义成员资格提供程序。自定义成员资格提供程序为其构造函数提供UserRepository
,该构造函数提供成员资格提供程序和NHibernate之间的接口。 UserRepository
由Ninject IoC容器提供。
然而,显然,当.NET实例化提供程序时,这不起作用:无参数构造函数没有UserRepository而且无法创建一个(UserRepository需要将NHibernate会话传递给它的构造函数),这意味着提供程序无法访问其数据存储。如何解决对象依赖?
值得注意的是,这是一个已经使用Ninject进行改造的现有应用程序。以前我使用无参数构造函数,它们能够与参数化构造函数一起创建所需的依赖项,以帮助进行单元测试。
有什么想法,或者我是否已将自己置于角落里?
答案 0 :(得分:5)
您可能希望保留无参数构造函数,即使用Ninject初始化所需的存储库。您可能希望使用Common Service Locator,因此您不需要在自定义提供程序中既没有对Ninject的引用也没有它的容器。似乎Ninject没有官方的CSL适配器实现,但写一个不应该很难(检查其他实现,如Windsor的),我确信在某处有一个非官方的实现。
答案 1 :(得分:5)
Michael B.来自Dependency injection and ASP.Net Membership Providers
的正确答案您可以通过以下方式获取您的存储库(或服务)注入:
public IRepository Repository { get { return DependencyResolver.Current.GetService(IRepository ); } }
答案 2 :(得分:4)
由于在Ninject可以实例化它们之前创建了成员资格集合和MemberShip.Provider实例,因此您需要对该对象执行创建后激活。如果您在提供程序类中使用[Inject]为属性标记依赖项,则可以调用kernel.Inject(MemberShip.Provider) - 这会将所有依赖项分配给您的属性。
答案 3 :(得分:-1)
我遇到了同样的问题,我通过使用身份验证票证将所需数据传递给身份对象来解决它。
然后不需要将对象注入成员资格提供者。
在我的身份验证码中
[NonAction]
private void SetAuthTicket(Member member, bool isPersistent)
{
HttpCookie cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName);
FormsAuthentication.SetAuthCookie(member.Email, isPersistent);
string userData = "|" + member.ID + "|" + member.Firstname + "|" + member.Lastname + member.Culture;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, member.Email, DateTime.UtcNow, DateTime.UtcNow.AddDays(7), isPersistent, userData);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(cookie);
}
在Global.asax中
void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
IPrincipal user = HttpContext.Current.User;
if (user.Identity.IsAuthenticated && user.Identity.AuthenticationType == "Forms")
{
FormsIdentity identity = user.Identity as FormsIdentity;
MyIdentity ai = new MyIdentity(identity.Ticket);
MyPrincipal p = new MyPrincipal(ai);
HttpContext.Current.User = p;
System.Threading.Thread.CurrentPrincipal = p;
if (!String.IsNullOrEmpty(ai.Culture))
{
CultureInfo ci = new CultureInfo(ai.Culture);
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
}
}
在Identity类中,我有MemberName,Firstname和Lastname属性,它们返回部分故障单字符串。