2017-08-05 79 views
1

我的控制器是这样的:如何在身份认证配置统一容器的AccountController

public class AccountController : ApiController 
{ 
    private const string LocalLoginProvider = "Local"; 
    private ApplicationUserManager _userManager; 
    private readonly ApplicationRoleManager _roleManager; 

    public AccountController() 
    { 
    } 

    public AccountController(ApplicationUserManager userManager, 
     ISecureDataFormat<AuthenticationTicket> accessTokenFormat, 
     ApplicationRoleManager roleManager) 
    { 
     UserManager = userManager; 
     AccessTokenFormat = accessTokenFormat; 
     _roleManager = roleManager; 

    } 
} 

在UnityConfig.cs我尝试配置像这样:

public static void RegisterTypes(IUnityContainer container) 
    { 
     // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements. 
     // container.LoadConfiguration(); 

     // TODO: Register your types here 
     container.RegisterType<AccountController>(new InjectionConstructor()); 
     container.RegisterType<ApplicationUserManager>(); 
     container.RegisterType<ApplicationRoleManager>(); 
     container.RegisterType<ISecureDataFormat<AuthenticationTicket>, SecureDataFormat<AuthenticationTicket>>(); 
    } 

在WebApiConfig.cs:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     var container = new UnityContainer(); 
     UnityConfig.RegisterTypes(container); 
     //Set the unity container as the default dependency resolver 
     config.DependencyResolver = new UnityHierarchicalDependencyResolver(container); 
    } 
} 

而且在Global.asax.cs中:

public class WebApiApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); // At the beginning, register with HttpConfiguration 
     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 
    } 
} 

但是当我尝试使用roleManager(var role = await _roleManager.FindByIdAsync(model.RoleId);)来检索作用,它说:

对象引用不设置到对象的实例。

我看到有一个类似的问题here,但它不能解决我的问题。

+0

哪一个是空的? '_roleManager'或'model'?鉴于涉及的对象,这是可能的。你需要调试,看看它是哪个 – Nkosi

+0

@Nkosi'model.RoleId'获得3和'_roleManager'在控制器初始化时注入。这不是问题,但在这里我确定我的UnityConfig有问题。 – Arif

+0

为什么你有无参数的构造函数? – Nkosi

回答

1

根据问题中代码的外观,我相信您使用的是ASP.NET Web API的Unity引导程序,它应该连接UnityDependencyResolver

container.RegisterType<AccountController>(new InjectionConstructor()); 

这注册了AccountController并指示Unity使用无参数的构造函数。这就是为什么你所有的依赖都是空的。如果你想使用其他的构造函数删除AccountController注册,Unity将使用最多参数的构造函数。但是,如果你这样做,那么你会得到一个运行时错误,试图解决AccountController,因为ISecureDataFormat<>未注册,Unity不知道如何将该接口映射到具体类型。

如果您注册了一个到SecureDataFormat<>的映射,那么还有一些额外的依赖项需要注册。

container.RegisterType(typeof(ISecureDataFormat<>), typeof(SecureDataFormat<>)); 
container.RegisterType<ITextEncoder, Base64UrlTextEncoder>() 
container.RegisterType<IDataSerializer<AuthenticationTicket>, TicketSerializer>()   
container.RegisterType<IDataProtector>(new ContainerControlledLifetimeManager(), 
    new InjectionFactory(c => new DpapiDataProtectionProvider().Create("App Name"))); 

请注意,上述注册未经测试。不知道你是否应该配置OWIN的数据保护(也许从OWIN配置获得保护提供者)。

以下两个注册并不是严格要求的,因为Unity知道如何在没有注册的情况下解析具体类型,也没有提供额外的InjectionMembers(例如生命期,参数覆盖等)。

container.RegisterType<ApplicationUserManager>(); 
container.RegisterType<ApplicationRoleManager>(); 
相关问题