访问routeattribute中的配置

时间:2018-04-09 20:22:30

标签: c# asp.net-core

我的API路由属性类就像这样

public class MyRouteAttribute : RouteAttribute
{
    private const string BaseRoute = "api/default";
    private const string PrefixRouteBase = BaseRoute + "/";
    public MyRouteAttribute() : base(BaseRoute)
    {

    }
    public MyRouteAttribute(string route):
        base(string.IsNullOrEmpty(route) ?
            BaseRoute : PrefixRouteBase + route)
        {

        }

}

它在像这样的控制器中使用

[MyRoute]
public class MyController : Controller
{
    .....
}

如果必须让路线可配置,如何将IOptions传递给MyRoute?

例如,如果我这样做:

public class MyRouteAttribute : RouteAttribute
{
    private const string BaseRoute = "api/default";

    public MyRouteAttribute(IOptions<ApiRouteBaseConfiguration> routeOptions) : 
        base(routeOptions.Value.Url)
    {

    }

    public MyRouteAttribute(IOptions<ApiRouteBaseConfiguration> routeOptions, string route):
        base(string.IsNullOrEmpty(route) ? (routeOptions.Value.Url: $"{routeOptions.Value.Url}/" + route)
    {

    }
}

然后我在此处收到错误[MyRoute]要求我通过IOptions

如何在MyRoute属性中访问配置

1 个答案:

答案 0 :(得分:1)

当从Reflection例程请求属性时,CLR的

属性实例are created。您无法通过任何DI容器强制实例化属性。

我看到两种可能的方法来解决您的挑战。它们都允许您具有可配置属性,但是配置不是通过属性构造函数设置的。

  1. 更简单的方法是通过在应用程序启动时加载的静态属性设置配置:

    public class MyRouteAttribute : RouteAttribute
    {
        public static ApiRouteBaseConfiguration RouteConfiguration { get; } = new ApiRouteBaseConfiguration();
    
        public MyRouteAttribute() :
            base(RouteConfiguration.Url)
        {
        }
    
        public MyRouteAttribute(string route) :
            base(string.IsNullOrEmpty(route) ? RouteConfiguration.Url : $"{RouteConfiguration.Url}/" + route)
        {
        }
    }
    

    配置(配置部分在此处命名为"Routing"):

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        Configuration.Bind("Routing", MyRouteAttribute.RouteConfiguration);
    }
    

    嗯,由于静态属性的使用,这个解决方案并不完美。然而,它非常简单,应该可以解决问题。

  2. 第二种可能的方法 - 使用属性注入模式进行属性配置,并将其设置为IApplicationModelProvider的自定义实现。 this answer中描述了这种方法,我不会在这里复制代码。