2017-10-05 161 views
2

目前,我有幾個這樣的電話調用通用延伸與動態generetad拉姆達

app.CreatePerOwinContext<BasicUserManager>(BasicUserManager.Create); 
app.CreatePerOwinContext<ADUserManager>(ADUserManager.Create); 
... 

的那些「創建」方法是每一個類的靜態成員。所以基本上它註冊了一個處理程序,只要我請求owinContext中的一個BasicUserManager對象就會被調用。

我希望像這樣的東西來替代它:

var types = AppDomain.CurrentDomain.GetAssemblies() 
        .SelectMany(s => s.GetTypes()) 
        .Where(p => typeof(AbstractUserManager).IsAssignableFrom(p) && !p.IsAbstract); 

foreach (var type in types) 
{ 
    app.RegisterUserManagers(type); 
} 

沒有問題爲止。 RegisterUserManagers是定義如下的擴展:

public static void RegisterSRTUserManager(this IAppBuilder app, Type type) 
{    
    var createPerOwinContextMethod = typeof(AppBuilderExtensions).GetMethods().Where(p => p.Name == "CreatePerOwinContext" && p.GetParameters().Count() == 2).FirstOrDefault().MakeGenericMethod(type); 

    var createMethod = type.GetMethod("Create", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); 

    var optionsType = typeof(IdentityFactoryOptions<>).MakeGenericType(type); 

    var delegateType = typeof(Func<,,>).MakeGenericType(optionsType, typeof(IOwinContext), type);         

    var body = Expression.Call(createMethod, Expression.Parameter(optionsType, "options"), Expression.Parameter(typeof(IOwinContext), "context"));    

    var func = Expression.Lambda(delegateType, body, Expression.Parameter(optionsType, "options"), Expression.Parameter(typeof(IOwinContext), "context")).Compile(); 

    createPerOwinContextMethod.Invoke(null, new object[] {app, func }); 
} 

編譯lambda表達式後,我得到一個異常:

其他信息:類型Microsoft.AspNet.Identity的」可變「選項」。 Owin.IdentityFactoryOptions`1 [SeguridadAuth.Login.BD> .AdminOrgUserManager]'從範圍''引用,但未定義。

我明白params應該通過引用傳遞給我,但我無法確定在這種情況下如何去做。

任何幫助真的很感激。

回答

1

只是在發佈問題後才知道。只需要將相同的參數引用傳遞給這兩種方法。

var optionsPar = Expression.Parameter(optionsType, "options"); 
var contextPar = Expression.Parameter(typeof(IOwinContext), "context"); 

var body = Expression.Call(createMethod, optionsPar, contextPar); 

var func = Expression.Lambda(delegateType, body, optionsPar, contextPar).Compile();