在Dot Net Core中用于配置服务的约定如下。
需要操作<>作为参数的方法
public static IServiceCollection AddAsResourceServer(this IServiceCollection services, Action<AuthMiddlewareOptions> action = null)
{
if(action != null)
{
AuthMiddlewareOptions authOptions = new AuthMiddlewareOptions();
action.Invoke(authOptions);
}
...
return services
}
这使我们可以按照以下步骤在启动时配置服务。
启动ConfigureServices方法
services.AddAsResourceServer((a) =>
{
a.Audience = "Long Audience";
a.Issuer = "provider.com/oauthprovider";
});
这真的很酷!我喜欢这种模式。它非常适合允许任何人覆盖基本配置选项。
但是,当您已经有该对象的实例时,这似乎非常麻烦。我将如何创建对象的实例,将其转换为动作,并将其传递给.AddAsResourceServer
方法?
我尝试过:
Action<AuthMiddleWareOptions> auth = new Action<AuthMiddleWareOptions>()
/// The above way still requires a "target" in constructor so it doesnt work.
///so i still need to pass each
///property into it.
我的服务使用者可能刚刚创建了AuthMiddleWareOptions实例,并通过appsettings进行填充!
他们可能已经做了类似的事情。
AuthMiddlewareOptions myoptions = new AuthMddlewareOptions();
Configuration.Bind("AuthMiddlewareOptions", myoptions);
现在它们具有“ myoptions”。有没有一种快速的方法可以将其与Action Parameter一起使用。也许是这样吗?
AuthMiddlewareOptions myoptions = new AuthMddlewareOptions();
Configuration.Bind("AuthMiddlewareOptions", myoptions);
services.AddAsResourceServer((a) => SpecialThing(myoptions));
答案 0 :(得分:2)
您只需将您的配置绑定到方法提供的选项实例。
services.AddAsResourceServer(options =>
{
Configuration.Bind("AuthMiddlewareOptions", options);
});
答案 1 :(得分:1)
您可以为一个选项类注册多个配置委托:
services.Configure<AuthMiddlewareOptions>(Configuration.GetSection("AuthMiddlewareOptions"));
services.AddAsResourceServer(options => SpecialThing(options));
并且 AddAsResourceServer 也应该调用services.Configure
:
public static IServiceCollection AddAsResourceServer(this IServiceCollection services, Action<AuthMiddlewareOptions> action = null)
{
if (action != null)
services.Configure(action);
// ...
return services;
}
具有此设置,从配置部分“ AuthMiddlewareOptions”填充 AuthMiddlewareOptions ,然后自定义委托( Specialthing )可以更改前一个填充的选项。步骤。
顺序很重要很重要!如果交换两行,则 SpecialThing 的更改将被来自配置的值覆盖。
答案 2 :(得分:0)
您需要以其他方式进行操作。
例如,由于找不到您的方法,我使用了AddAuthorization
:
services.AddAuthorization(c =>
{
c.DefaultPolicy = null;
});
可以使用以下方法进行配置:
public static void Config(AuthorizationOptions configure, IConfiguration configuration)
{
configure.DefaultPolicy = null;
//Configuration.Bind("AuthMiddlewareOptions", myoptions);
}
您可以这样做:
services.AddAuthorization(c => Config(c, Configuration));
问题是,在这些Action<T>
方法中,您获得了已实例化的对象T
。因此,您需要将自定义创建的对象复制到该对象。通过上面的操作,我们更改了API,因此将其配置在正确的对象上。
答案 3 :(得分:-1)
我尝试了许多模式,直到我将鼠标悬停在方法中的a
上才意识到它不是Action<AuthMiddlewareOptions>
类型,但实际上是AuthMiddleWareOptions
。所以这个非常简单的任务就可以了!
services.AddAsResourceServer(a => a = myoptions);
答案 4 :(得分:-1)
您的问题“将对象的实例传递给以Action <>作为参数的方法”的快速答案是“不,您不能”
但是,作为解决方法,您可以简单地对对象进行深层克隆,以交换“内部”选项的属性。
类似这样的东西:
static class Copy
{
public static void ObjectToAnother<T>(T source, T target)
{
foreach (var sourceProp in source.GetType().GetProperties())
{
var targetProp = target.GetType().GetProperty(sourceProp.Name);
targetProp.SetValue(target, sourceProp.GetValue(source, null), null);
}
}
}
您可以这样使用:
var obj = new Obj();
Foo.Bar((a) =>
{
Copy.ObjectToAnother(a, obj);
});
应该可以