2017-04-06 63 views
2

我試圖用asp.net身份使用ninject,目前我做了綁定如下:Ninject用asp.net身份

kernel.Bind(typeof(IUserStore<>)).To(typeof(UserStore<>)); 

這裏有類定義:

public interface IUser : IUser<string> 

public interface IUserStore<TUser> : IUserStore<TUser, string>, IDisposable where TUser : class, IUser<string> 

public class IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>, IGenerateKeys 

public class UserStore<TUser> : UserStore<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUserStore<TUser>, IUserStore<TUser, string> where TUser : IdentityUser, new() 

public class Context { 
    public Context(ILogger Logger, Dictionary<string, string> LocalConfig, IUserStore<IUser> UserManager 
     ){...} 
} 

當我嘗試做kernel.Get<Context>()時,出現無法將IUserStore投射到UserStore的錯誤。

Unable to cast object of type 'UserStore`1[IdentityUser]' to type 'Microsoft.AspNet.Identity.IUserStore`1[Microsoft.AspNet.Identity.IUser]'. 

我真的不明白爲什麼這是行不通的,但事實上是在試圖以下IUserStore<IdentityUser> dummy = new Store<IdentityUser>()沒有給出編譯錯誤,但是這確實IUserStore<IUser> dummy = new Store<IdentityUser>(),但我不能understande爲什麼,因爲IdentityUser實現IUSER。

任何人有類似的問題嗎?

+1

你是混淆與類型本身泛型參數。當你改變一個通用對象的類型參數時,你改變它的實際類型。所以'IUserStore '與IUserStore 不是一回事,你不能指定一個給另一個。想象一下,試圖將一個「列表」分配給「列表」。如果泛型類型是彼此的實現,則無關緊要。現在,您可以將一個IdentityUser對象添加到IUserStore 對象,但這與嘗試分配另一個類型的實際UserStore不同。 –

+1

我應該澄清一點。雖然我上面提到的是真實的,但是基於.NET 4的語言(C#和VB)有許多方法可以做到這一點,但它需要指定接口來執行此操作。這就是所謂的協變(或相反方式)。 IUser和IUserStore接口沒有實現,所以這個觀點依然存在。您可以在這裏閱讀更多有關方差:https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx –

回答

1

如果你看一下Microsoft.AspNet.Identity.EntityFramework你可以看到在TUSER必須UserStore是IdentityUser而不是IUSER的類型,這就是爲什麼你得到了編譯錯誤。

public namespace Microsoft.AspNet.Identity.EntityFramework 
{ 
// 
// Summary: 
//  EntityFramework based user store implementation that supports IUserStore, IUserLoginStore, 
//  IUserClaimStore and IUserRoleStore 
// 
// Type parameters: 
// TUser: 
public class UserStore<TUser> : UserStore<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUserStore<TUser>, IUserStore<TUser, string>, IDisposable where TUser : IdentityUser 
{ 
    // 
    // Summary: 
    //  Default constuctor which uses a new instance of a default EntityyDbContext 
    public UserStore(); 
    // 
    // Summary: 
    //  Constructor 
    // 
    // Parameters: 
    // context: 
    public UserStore(DbContext context); 
    } 
} 

您應始終使用IdentityUser,因爲IUser只是IdentityUser的最小接口。

如果你想使用Ninject與身份,這將是一個精簡版有點棘手,你可以找到一步一步的解決方案在這裏:How to inject User Manager to Account Controller with default Identity Model in Identity 2 using Ninject