2017-08-05 78 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>(); 
相關問題