我有一个使用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容器中全局过滤器的调用。在我看来,这似乎是一种反模式,或者应该有更好的方法来做到这一点。
答案 0 :(得分:3)
配置容器和调用容器以解析Filter
实例的方式没有实际问题,只要所有这些工作都在composition root完成。
我认为潜在的问题是使用Attributes
的方式不打算使用它们。关于此主题的有用读物是Steven在Dependency 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);
}
哪个更直接,并且从其他位置消除逻辑,这可能会让人感到困惑。