在其构造函数中使用服务为全局筛选器配置DI容器

时间:2014-12-30 14:02:26

标签: 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*

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, Container);
    }
}

我的RegisterGlobalFilters看起来像这样:

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>());
    }
}

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

2 个答案:

答案 0 :(得分:3)

配置容器和调用容器以解析Filter实例的方式没有实际问题,只要所有这些工作都在composition root完成。

我认为潜在的问题是使用Attributes的方式不打算使用它们。关于此主题的有用读物是StevenDependency Injection in Attributes: don’t do it!Mark Seemann帖子Passive Attributes上的帖子。如果您按照这些帖子中的建议行事,我认为您最终会发现自己感觉更满意的代码。

另请参阅Steven here最近提出的关于MVC属性的单身性质的问题。

答案 1 :(得分:0)

经过与系统架构师的一些讨论后,我们得出(令人尴尬的简单)结论,我们架构的最佳答案是在DI容器中创建两个Register函数 - 一个名为RegisterCorporateWebSiteDependencies(),另一个名为RegisterStoreWebsiteDependencies( )。

其自然扩展还包括2个全局过滤器配置,在依赖关系组合之后调用,(同样)一个用于RegisterCorporateGlobalFilters(),另一个用于RegisterStoreGlobalFilters()。

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

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

哪个更直接,并且从其他位置消除逻辑,这可能会让人感到困惑。