[英]Multiple interceptors in NHibernate
I am very new to NHibernate and have been following various tutorials online, especially this one to create my own program. 我对NHibernate还是很陌生,并且一直在网上关注各种教程,尤其是用这一教程来创建自己的程序。 I really liked the use of the interceptor to add
INotifyPropertyChanged
to entities created using the DataBindingFactory
and tried to follow the same idea to add IDataErrorInfo
to entities created by the DataBindingFactory
with another method CreateWithValidation(Type type)
: 我真的很喜欢使用拦截器将
INotifyPropertyChanged
添加到使用DataBindingFactory
创建的实体中,并尝试遵循相同的想法通过另一个方法CreateWithValidation(Type type)
将IDataErrorInfo
添加到由DataBindingFactory
创建的实体中:
public static object CreateWithValidation(Type type)
{
return _proxyGenerator.CreateClassProxy(type, new[]
{
typeof (IDataErrorInfo),
typeof (INotifyPropertyChanged)
}, new IInterceptor[]
{
new NotifyPropertyChangedInterceptor(type.FullName),
new DataErrorInfoInterceptor()
});
}
The code for the NotifyPropertyChangedInterceptor
is the same as in the linked article and below is my implementation of the DataErrorInfoInterceptor
class which came from this article : 对于代码
NotifyPropertyChangedInterceptor
相同链接的文章中和下面是我实现的DataErrorInfoInterceptor
这些来自一流的这篇文章 :
public class DataErrorInfoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.DeclaringType.Equals(typeof(IDataErrorInfo)))
{
var validator = new ValidatorEngine();
var errors = validator.Validate(invocation.Proxy);
if (invocation.Method.Name.Equals("get_Item"))
{
String propertyName = Convert.ToString(invocation.Arguments[0]);
var propertyErrors = errors
.Where(e => e.PropertyName.Equals(propertyName))
.Select(e => e.Message)
.ToArray();
if (propertyErrors.Count() > 0)
{
invocation.ReturnValue = string.Join(Environment.NewLine, propertyErrors);
}
else
{
invocation.ReturnValue = null;
}
}
else if (invocation.Method.Name.Equals("get_Error"))
{
var allErrors = errors
.Select(e => e.Message)
.ToArray();
if (allErrors.Count() > 0)
{
invocation.ReturnValue = string.Join(Environment.NewLine, allErrors);
}
else
{
invocation.ReturnValue = null;
}
}
else
{
invocation.Proceed();
}
}
}
The problem that I have is that if I create an object using the CreateWithValidation()
method and use it on a model, any text I enter into a textbox on the view is cleared when I tab away from the field (this probably happens in other fields as well but I've only tried it on textboxes). 我遇到的问题是,如果我使用
CreateWithValidation()
方法创建一个对象并在模型上使用它,那么当我离开该字段时,输入到视图上文本框中的任何文本都会被清除(这可能会在其他情况下发生)字段,但我只在文本框上尝试过)。 I suspect that this is because both of the classes implementing IInterceptor
have the line invocation.Proceed()
if the method that has been intercepted is not one that the class is interested in. 我怀疑这是因为如果已拦截的方法不是该类感兴趣的方法,则两个实现
IInterceptor
的类都具有invocation.Proceed()
行。
My question is, is it possible to have two interceptors like this or do I have to have one massive class, eg: CustomInterceptor
which has all of the methods for, eg: INotifyPropertyChanged
and IDataErrorInfo
and deal with them there? 我的问题是,是否可能有两个这样的拦截器,或者我是否必须有一个大型类,例如:
CustomInterceptor
,它具有所有方法,例如: INotifyPropertyChanged
和IDataErrorInfo
并在那里处理? That seems quite unwieldy to me. 对我来说,这似乎很笨拙。
For what it's worth, this is how I set the interceptor on my SessionFactory
: 对于它的价值,这就是我在
SessionFactory
上设置拦截器的方式:
public static void Initialise()
{
Configuration config = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c
.Server("")
.Database("")
.Username("")
.Password("")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Map>()
.Conventions.AddFromAssemblyOf<EnumConvention>())
.BuildConfiguration();
ConfigureNhibernateValidator(config);
DataBindingInterceptor interceptor = new DataBindingInterceptor();
SessionFactory = config
.SetInterceptor(interceptor)
.BuildSessionFactory();
}
The problem is not multiple interceptors. 问题不在于多个拦截器。 And the problem is not calling
invocation.Proceed()
. 问题不在于调用
invocation.Proceed()
。 The problem is that you don't call invocation.Proceed()
in your DataErrorInfoInterceptor
when the method is not from IDataErrorInfo
(it's correct in the linked article). 问题是,当方法不是来自
IDataErrorInfo
时,您不会在DataErrorInfoInterceptor
调用 invocation.Proceed()
(在链接的文章中是正确的)。 Because of this, when you call some getter or setter, nothing happens. 因此,当您调用某个getter或setter时,什么也不会发生。
Right now, you have something like this: 现在,您会看到以下内容:
if (invocation.Method.DeclaringType.Equals(typeof(IDataErrorInfo)))
{
if (invocation.Method.Name.Equals("get_Item"))
{
// some code
}
else if (invocation.Method.Name.Equals("get_Error"))
{
// more code
}
else
{
invocation.Proceed();
}
}
What you should have is this: 您应该拥有的是:
if (invocation.Method.DeclaringType.Equals(typeof(IDataErrorInfo)))
{
if (invocation.Method.Name.Equals("get_Item"))
{
// some code
}
else if (invocation.Method.Name.Equals("get_Error"))
{
// more code
}
}
else
{
invocation.Proceed();
}
Next time, try stepping through the code in debugger to see what's really going on. 下次,尝试逐步调试程序中的代码以查看实际情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.