使用ASP MVC和Castle Windsor将数据库注入到validation属性中

我需要一些帮助 – 我试图在需要进行数据库调用的ASP.NET MVC Web项目中使用自定义validation属性。

我有windsor成功地为控制器工作,并正常注入IRepository接口。 当我需要将存储库注入属性类时,问题就出现了。

属性类具有以下代码:

public class ValidateUniqueUrlNodeAttribute : AbstractValidationAttribute { private readonly string message; private readonly IArticleRepository articleRepository; public ValidateUniqueUrlNodeAttribute(string message) { this.message = message; } public ValidateUniqueUrlNodeAttribute(string message, IArticleRepository articleRepository):this(message) { this.articleRepository = articleRepository; } public override IValidator Build() { var validator = new UniqueUrlNodeValidator(articleRepository) { ErrorMessage = message }; ConfigureValidatorMessage(validator); return validator; } 

我的问题是,我似乎无法让Windsor拦截传递给IArticleRepository的属性的构造

我的global.asax文件中的当前代码如下:

 container = new WindsorContainer(); ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container)); container .RegisterControllers(Assembly.GetExecutingAssembly()) .AddComponent() .AddComponent(); 

任何帮助将不胜感激。

AFAIK没有dependency injection容器可以直接管理属性,因为它是由运行时实例化的,并且没有办法拦截它。

但是,他们可以通过以下方式作弊

  1. 使用静态网关到容器( 示例 ),或
  2. 使用注入任何依赖关系的“BuildUp”function可在已构造的对象中找到。 这在Unity中称为BuildUp,在 Autofac中称为InjectProperties 。

Windsor不支持#2( ref1 , ref2 ),所以你可以:

  1. 尝试其中一个黑客使Windsor支持#2( hack1 , hack2 )
  2. 使用静态网关
  3. 实现自己的IValidatorBuilder ,并使用Windsor创建validation器。 我确定这是在某处实现但我现在找不到它…

不知道这是否有帮助,但我将ValidationAttribute子类ValidationAttribute暴露Resolve()方法,如下所示:

 public abstract class IocValidationAttribute : ValidationAttribute { protected T Resolve() { return IocHelper.Container().Resolve(); } } 

然后它可以在需要命中数据库的任何自定义ValidatorAttribute中使用:

 public class UniqueEmailAttribute : IocValidationAttribute { public override bool IsValid(object value) { ICustomerRepository customerRepository = Resolve(); return customerRepository.FindByEmail(value.ToString()) == null; } } 

我认为这是Mauricio Scheffer提到的“静态网关”方法的变体。 我不知道这是不是一个好的设计。 我不是它的忠实粉丝,我宁愿dependency injection更“优雅”,虽然我不能明显地使用构造函数注入,我想使用Property注入但是无法找到方法挂钩到ASP.NET MVC框架代码来做到这一点(我甚至仔细考虑了MVC2源代码)。

我能够连接它[在发生这种情况时使用Autofac,但它只是通过ASP.NET MVC DependencyResolver构造函数注入] ,这使得一个人可以编写:

 class MyModel { ... [Required, StringLength(42)] [ValidatorService(typeof(MyDiDependentValidator), ErrorMessage = "It's simply unacceptable")] public string MyProperty { get; set; } .... } public class MyDiDependentValidator : Validator { readonly IUnitOfWork _iLoveWrappingStuff; public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff) { _iLoveWrappingStuff = iLoveWrappingStuff; } protected override bool IsValid(MyModel instance, object value) { var attempted = (string)value; return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted); } } 

有了一些帮助类(看看那里),你可以在例如ASP.NET MVC中连接它,就像在Global.asax : –

 DataAnnotationsModelValidatorProvider.RegisterAdapterFactory( typeof(ValidatorServiceAttribute), (metadata, context, attribute) => new DataAnnotationsModelValidatorEx(metadata, context, attribute, true)); 

嗯。

你能否测试删除(字符串消息)ctor的效果,看看是否至少迫使Castle将ctor与Repostiory一起使用?

否则我们调用AddComponent(name,type,type)。 除此之外,它真的应该工作……

这也暗示了我的第一个想法吗? 如何使用Windsor将依赖项注入ActionFilterAttributes