2010-10-25 23 views
5

Bir arabirim kullanarak kısmi bir sınıfım var çünkü Entity Framework 4'ten otomatik olarak oluşturulmuş ve bu nedenle ObjectContext öğesinin mirasını alan diğer kısmi sınıf nedeniyle orijinal bir özet sınıfının ne olduğunu devralmam.Inherited C# Sınıfı "Referans" kaybediliyor

benim kısmi sınıf için aşağıdaki adres:

namespace Utilities.BusinessRules 
{ 
    using Microsoft.Practices.EnterpriseLibrary.Validation; 

    public interface IBusinessObject 
    { 
     void AddRule(BusinessRule rule); 

     void Validate(ValidationResults results); 
    } 
} 

Ve uygulama:

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); 
     } 
    } 
} 

İşte arayüzü

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)); 
       } 
      } 
     } 
    } 
} 

kuralları endişe etmeyin, çalışırlar. Problem, bir test projesinde soyut bir sınıf kullanmam durumunda, BusinessObject'teki Validate() yönteminin, soyut sınıfı (bu örnekte, MyObject olmasını beklerim) herhangi bir sınıf olarak doğru bir kimlik (bu) tanımlayacaktır. Maalesef, bir Arayüze geçmek, (bu) devralma sınıfını kaybeder ve bunun yerine BusinessObject olarak tanımlar.

Devralma sınıfı uygun şekilde tanımlanabilmesi için nasıl yapabilirim?

İşte çağıran konsol sınıfı var:

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(); 
      } 
     } 
    } 
} 

Bu geçerli olmalıdır ancak (bu) yerine MyObject tipi BusinessObject olduğu belirlenirse, çünkü yerine geçersiz olacaktır.

Argh! Çok yakınım, oldukça sinir bozucu.

Richard

+0

Neden "public Comment()" bir dönüş türüne sahip değil? – leppie

+0

Bu bir kurucu, dolayısıyla bir dönüş türü yok. – Richard

cevap

2

Ben BusinessObject senin uygulaması bunun kalıtsal olacağını varsayarak yazılır inanıyoruz. Ancak, şimdi bir kompoze nesne olarak kullanmaktan r göre, birkaç değişiklik yapmak gerekir:

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)); 
      } 
     } 
    } 
} 

Ve aşağıdaki gibi kullanırız:

[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); 
    } 
} 

Esasen, söylediğimiz biz olacak o validator harici bir uygulama var ve bu nedenle validate yöntemine iletilen hedef nesneye (valide edilmiş) sahip olmamız gerekiyor. BusinessObject'i BusinessObjectValidtor olarak yeniden adlandırmanızı da öneririm.

+0

Merhaba, cevabınız için teşekkürler. Bu kesinlikle almanın yönü, bence. Ancak BusinessObject, BusinessObjectValidator (iyi nokta) olarak yeniden adlandırılırsa, kodunuzda IBusinessObject/BusinessObject öğesinin adı nedir? – Richard

+0

Anladım! Bu ikinci bir arayüz. Küçük bir çimdikle, şimdi çalışıyorum :) Çok teşekkürler. – Richard

İlgili konular