Asp.net mvc 4 为全局筛选器配置DI容器,其构造函数中包含服务

Asp.net mvc 4 为全局筛选器配置DI容器,其构造函数中包含服务,asp.net-mvc-4,architecture,dependency-injection,simple-injector,Asp.net Mvc 4,Architecture,Dependency Injection,Simple Injector,我有一个使用SimpleInjector和MVC的站点,我试图确定我在架构上的错误 我正在设置DI容器: public static class DependencyConfig { private static Container Container { get; set; } public static void RegisterDependencies(HttpConfiguration configuration) { *snip*

我有一个使用SimpleInjector和MVC的站点,我试图确定我在架构上的错误

我正在设置DI容器:

public static class DependencyConfig
{
    private static Container Container { get; set; }

    public static void RegisterDependencies(HttpConfiguration configuration)
    {
          *snip*

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, Container);
    }
}
我的RegisterGlobalFilter如下所示:

public static class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters, Container container)
    {
        filters.Add(new HandleErrorAttribute());

        filters.Add(container.GetInstance<OrderItemCountActionFilterAttribute>());

        if (container.GetInstance<ISiteConfiguration>().ConfiguredForExternalOrders)
        {
            filters.Add(container.GetInstance<StoreGeolocationActionFilterAttribute>());
        }

        filters.Add(container.GetInstance<StoreNameActionFilterAttribute>());
    }
}
公共静态类过滤器配置
{
公共静态无效注册表全局过滤器(全局过滤器集合过滤器,容器)
{
filters.Add(新HandleErrorAttribute());
filters.Add(container.GetInstance());
if(container.GetInstance().ConfiguredForExternalOrders)
{
filters.Add(container.GetInstance());
}
filters.Add(container.GetInstance());
}
}

商店可以在店内信息亭或在家在线接受订单(通过本网站)。外部订单需要地理定位,以便向客户显示有关其最近商店的信息。但这意味着我必须在全局过滤器中使用容器作为服务定位器,这意味着我必须在DI容器中隐藏对全局过滤器的调用。在我看来,这一切似乎都是一种反模式,或者应该有更好的方法来做到这一点。

只要所有这些工作都是在系统中完成的,那么配置容器和调用容器来解析
过滤器
实例的方式就没有真正的问题

在我看来,根本的问题是使用
属性的方式不符合预期。关于这一主题的有用读物有上的帖子和上的帖子。如果你按照这些帖子中的建议去做,我想你会发现你最终得到了你更满意的代码


另请参见Steven最近提出的关于MVC属性的单例性质的问题。

在与系统架构师进行了一些讨论后,我们得出了(令人尴尬的简单)结论是,对于我们的体系结构来说,最好的解决方案是在DI容器中创建两个寄存器函数——一个称为RegisterCorporateWebSiteDependencies(),另一个称为RegisterStoreWebsiteDependencies()

它的自然扩展是在依赖项组合之后调用2个全局筛选器配置,(同样)一个用于RegisterCorporateGlobalFilters(),另一个用于RegisterStoreGlobalFilters()

这将导致运行寄存器ex的一个整体if语句:

if (Convert.ToBoolean(ConfigurationManager.AppSettings["IsCorporate"]))
{
    DependencyConfig.RegisterCorporateWebSiteDependencies(GlobalConfiguration.Configuration);
}
else
{
    DependencyConfig.RegisterStoreWebSiteDependencies(GlobalConfiguration.Configuration);
}

这更为简单,并且消除了其他容易混淆的地方的逻辑。

我读了Ploeh博客,我完全错过了这篇文章,但我似乎无法确定如何为MVC和全局过滤器实现它。顺便说一句,我担心这个答案会被标记为仅链接的答案,因为这里没有非链接文本。@CBauer评论太长了。有一个关于的工作示例。@CBauer您是否向下滚动到最后一条评论?是的,它只讨论了如何添加SimpleInputActionFilterProvider,而不是SimpleInputActionFilterProvider中对web api的8+引用。@CBauer我想所有这些类型都是在文章的其他地方定义的?