注意:我最初将此页面命名为“方法通过Unity将对象注入启动变为空”;对方法注入的所有其他引用应该被理解为 property 注入。
我在Asp.Net MVC5项目中使用unity,我最初是通过Unity.Mvc5 nuget包安装的。由于我已将AspNet Identity内容移入其自己的项目中,因此我很难通过app.GetDataProtectionProvider()为其自定义ApplicationUserManager提供对DataProtectionProvider的访问,这可以通过Startup.ConfigureAuth(IAppBuilder应用程序)中的MVC应用程序获得。 (如果标识内容仍在Web项目中,我会按照trailmax的建议进行此操作:http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/)
我已经定义了一个DataProtectionProviderFactory类,如下所示:
public class DataProtectionProviderFactory : MVC5.Web.Identity.IDataProtectionProviderFactory
{
private IDataProtectionProvider _dp;
public void SetProvider(IDataProtectionProvider dp)
{
_dp = dp;
}
public IDataProtectionProvider GetProvider()
{
return _dp;
}
}
然后设置Startup类以及ApplicationUserManager类,以便通过Unity注入方法。在身份项目中,我有:
public class ApplicationUserManager : UserManager<IdentityUser, Guid>
{
public IDataProtectionProviderFactory DataProtectionProviderFactory { get; set; }
.
.
}
在Web项目中,我有
public partial class Startup
{
public IDataProtectionProviderFactory DataProtectionProviderFactory { get; set; }
public void ConfigureAuth(IAppBuilder app )
{
DataProtectionProviderFactory.SetProvider(app.GetDataProtectionProvider());
}
}
我的UnityConfig.cs文件(基本上):
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager(), new InjectionConstructor("Mvc5"));
container.RegisterType<IDataProtectionProviderFactory, DataProtectionProviderFactory>();
container.RegisterType<UserManager<IdentityUser, Guid>, ApplicationUserManager>(new HierarchicalLifetimeManager(),
new InjectionProperty("DataProtectionProviderFactory"));
container.RegisterType<Startup>(new HierarchicalLifetimeManager(),
new InjectionProperty("DataProtectionProviderFactory"));
container.RegisterType<IUserStore<IdentityUser, Guid>, UserStore>(new HierarchicalLifetimeManager());
container.RegisterType<CustomSigninManager>(new HierarchicalLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
// Startup.DataProtectionProviderFactory is non-null, after resolving in the following line
var start = container.Resolve<Startup>();
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
}
}
如果我在行上的RegisterComponents()中断:
var start = container.Resolve<Startup>();
然后我可以看到Startup.DataProtectionProviderFactory非空。
但是,当随后执行Startup.ConfigureAuth(IAppBuilder app)时,它的Startup.DataProtectionProviderFactory为null。
按照mnwsmit的建议进行初始更改后,我在UnityConfig.RegisterComponents()调用中添加了一个“new Startup()”参数,产生以下结果:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents(new Startup());
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
}
}
答案 0 :(得分:1)
调用Startup
的{{1}}类的实例由OWIN而不是Unity创建。因此,在您的设置中,您最终得到了ConfigureAuth
类的两个实例,一个注入了依赖项,另一个没有。没有办法让Unity注入依赖于OWIN(你真正的创业公司)创建的实例。您应该对规则进行一个例外,并使用容器作为服务定位器来获取Startup
实例,并确保DataProtectionProviderFactory
类获取该实例并使用它。例如,如下所示:
Startup