我有一个使用接口的部分类,因为我无法继承原始抽象类,因为其他部分类是从Entity Framework 4自动生成的,因此已经继承了ObjectContext。
我的部分课程有以下内容:
namespace Model
{
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Utilities.BusinessRules;
using Utilities.BusinessRules.Rules;
[HasSelfValidation]
public partial class MyObject : IBusinessObject
{
private readonly IBusinessObject businessObject = new BusinessObject();
private IBusinessObject BusinessObject
{
get
{
return businessObject;
}
}
public Comment()
{
AddRule(new ValidateRequired("Title"));
}
public void AddRule(BusinessRule rule)
{
BusinessObject.AddRule(rule);
}
[SelfValidation]
public void Validate(ValidationResults results)
{
BusinessObject.Validate(results);
}
}
}
这是界面:
namespace Utilities.BusinessRules
{
using Microsoft.Practices.EnterpriseLibrary.Validation;
public interface IBusinessObject
{
void AddRule(BusinessRule rule);
void Validate(ValidationResults results);
}
}
实施:
namespace Utilities.BusinessRules
{
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
public class BusinessObject : IBusinessObject
{
private readonly IList<BusinessRule> businessRules = new List<BusinessRule>();
public void AddRule(BusinessRule rule)
{
this.businessRules.Add(rule);
}
[SelfValidation]
public void Validate(ValidationResults results)
{
foreach (var rule in this.businessRules)
{
if (!rule.Validate(this))
{
results.AddResult(new ValidationResult(rule.ErrorMessage, this, rule.Key, rule.Tag, null));
}
}
}
}
}
不要担心规则,他们的工作。问题是如果我在测试项目中使用抽象类,那么BusinessObject中的Validate()方法将正确地标识(this)为继承抽象类的任何类(在此示例中,我希望它是MyObject)。 不幸的是,切换到接口,(这)丢失了继承类,而是将其标识为BusinessObject。
如何才能正确识别继承类?
这是调用控制台类:
namespace ModelConsumer
{
using Model;
using System;
using Microsoft.Practices.EnterpriseLibrary.Validation;
class Program
{
static void Main(string[] args)
{
using (var myEntities = new MyEntities())
{
var myObject= new MyObject();
myObject.Title = "Credo";
var validationResults = Validation.Validate(myObject);
if (validationResults.IsValid)
{
myEntities.MyObjects.AddObject(myObject);
//myEntities.SaveChanges();
Console.WriteLine("Valid.");
}
else
{
foreach (var validationResult in validationResults)
{
Console.WriteLine(validationResult.Message);
}
}
Console.Read();
}
}
}
}
这应该是有效的,但是会变得无效,因为(this)被标识为类型为BusinessObject而不是MyObject。
哎呀!我很亲密,这很令人烦恼。
理查德
答案 0 :(得分:2)
我相信您的BusinessObject实现是在假设它将被继承的情况下编写的。但是,现在您将其用作组合对象,您需要进行一些更改:
public interface IBusinessObjectValidator
{
void AddRule(BusinessRule rule);
void Validate(IBusinessObject target, ValidationResults results);
}
Public class BusinessObject: IBusinessObjectValidator
{
...
public void Validate(IBusinssObject target, ValidationResults results)
{
foreach (var rule in this.businessRules)
{
if (!rule.Validate(target))
{
results.AddResult(new ValidationResult(rule.ErrorMessage, target, rule.Key, rule.Tag, null));
}
}
}
}
您将按如下方式使用它:
[HasSelfValidation]
public partial class MyObject : IBusinessObject
{
private readonly IBusinessObjectValidator validator = new BusinessObject();
private IBusinessObjectValidator BusinessObjectValidator
{
get
{
return validator ;
}
}
public Comment()
{
AddRule(new ValidateRequired("Title"));
}
public void AddRule(BusinessRule rule)
{
validator .AddRule(rule);
}
[SelfValidation]
public void Validate(ValidationResults results)
{
validator.Validate(this, results);
}
}
基本上,我们说我们将在外部实现验证器,因此,我们需要将目标对象(正在验证)传递给validate方法。我还建议将BusinessObject重命名为BusinessObjectValidtor。