我可以使用Ninject将依赖项注入属性而不是使用服务定位器模式吗?

时间:2013-08-08 21:36:22

标签: asp.net-mvc ninject anti-patterns service-locator

我正在使用功能标志在不同环境中有选择地启用/禁用我的MVC4 Web应用程序的某些方面。我有一个名为IConfiguration的接口,带有IsEnabled(FeatureFlag)方法,可以访问这些标志。

为此,我想在关闭与其相关的功能时禁用某些MVC操作方法。我有一个名为FeatureAttribute的属性,定义如下:

// Usage: [Feature(FeatureFlag.I18N)]
public class FeatureAttribute : ActionMethodSelectorAttribute {
    private IConfiguration _config;
    private FeatureFlag _feature;

    public FeatureAttribute(FeatureFlag feature) {
        _config = DependencyResolver.Current.GetService<IConfiguration>();
        _feature = feature;
    }
    public override bool IsValidForRequest(ControllerContext controllerContext,
                                           MethodInfo methodInfo) {
        return _config.IsEnabled(_feature);
    }
}

这有效,but using DependencyResolver to get an instance of IConfiguration smells funny。有什么办法可以重新设计我的代码以避免服务定位器模式吗?

我最初想过使用filter injection,但ActionMethodSelectorAttribute实际上并不是过滤器,所以它不适用于此。

1 个答案:

答案 0 :(得分:2)

属性由.NET Framework创建。所以你不能做构造函数注入。注入属性的唯一两种方法是执行PropertyInjection或ServiceLocation。

PropertyInjection可以像这样完成:

  1. 添加使用您的属性(或IPlanningStrategy)的反射进行扫描的ActionMethodSelectorAttribute。如果不是控制器,立即返回。
  2. 具有此属性的Foreach方法添加IDirective,其中包含对MethodInfo的引用
  3. 使用IActivationStrategy添加注入属性的kernel.Inject(attribute)
  4. 最好看看Ninject的PropertyInjection实现,它的工作方式与此完全相同。只需要做一些改变就可以做你想做的事。