2011-02-25 50 views
1

我正在閱讀存儲庫的使用情況。有時我發現存儲庫是實體的一個屬性。我想知道親們是什麼。C#爲什麼使用存儲庫作爲屬性?

public interface IRepository<T> 
{ 
    T GetById(int id); 
    void Update(T); 
} 

public class FooRepository : IRepository<Foo> 
{ 
    public Foo GetById(int i) 
    { /* code ..*/ } 

    void Update(Foo) 
    { /*code..*/ } 
} 

public class Foo 
{ 
    public IRepository Repository {get;set;} 

    public void Update() 
    { 
    Repository.Update(this); 
    } 
} 

爲什麼使用這個apporach?使用存儲庫和實體對象分離更有意義嗎?這樣實體對象不知道任何存儲庫?

編輯:

但是,如果你有一個主要的對象和不同的子對象:

public class MainObject 
{ 
    public int Id {get;set;} 

    public List<ISubject> SubObjects {get;} 
} 

public interface ISubObject 
{ 
} 

public class SubObjectA : ISubObject 
{ 
    public string SomeProperty {get;set;} 
    public int Id {get;set;} 

    public int MainObjectId {get;set;} 
} 

public class SubObjectB : ISubObject 
{ 
    public string AnotherProperty{get;set;} 
    public int Id {get;set;} 

    public int MainObjectId {get;set;} 
} 

所以SubObjectA和SubObjectB是不同的類型,但實現ISubject接口。主對象具有這些子對象的列表。每個子對象都有它自己的存儲庫。你將如何加載子對象?

回答

3

一些實體的實現需要訪問它們所創建的背景下,實現延遲加載的例子。考慮以下幾點:

class MyEntity 
{ 
    public virtual IEnumerable<string> Tags { get; private set; } 
} 

interface IMyEntityRepository 
{ 
    ... 
} 

您可以從一個myEntity所實現,需要創建它的庫參考myEntity所返回的子類。

internal class MyLazyEntity : MyEntity 
{ 
    public MyLazyEntity(MyLazyEntityRepository repository) 
    { 
     this.Repository = repository; 
    } 

    public override IEnumerable<string> Tags 
    { 
     get 
     { 
      return this.Repository.LoadTagsForEntityFromXml(this.Id); 
     } 
    } 
} 

class MyLazyEntityRepository : IMyEntityRepository { } 

我會說,是保持在從實體派生的類的源代碼庫的引用是好的,另一方面,基礎機構類不應該有關於存儲庫的知識。

+0

在這種情況下,你有一個實體是一個子類,我的意思是一個子對象是一個完全不同的對象,它不從基礎實體繼承,但是所有的子對象實現了相同的界面你所描述的方法在這種情況下是否相同? – Martijn 2011-02-25 09:52:40

+0

在你的實體上有一個名爲「Update」的方法,這意味着它不是「持久性無知」如果這是你想要的,比requiri將IRepository設置爲屬性是非常好的。如果「Foo」打算成爲持久性無知的POCO類,那麼添加一個IRepository作爲該類的一部分將違反這種無知。如果Foo的意圖是持續無知,則爲 – 2011-02-25 10:05:36

+0

。你將如何實現這一點? – Martijn 2011-02-25 10:17:10

1

我不會使用這種方法。它不是Foo有責任更新自己的存儲庫責任。如果你正在應用持續的無知模式。

此代碼是一個氣味:

public void Update() 
    { 
    Repository.Update(this); 
    } 

它沒有做任何事情,但呼叫轉發到存儲庫。

+0

但是,如果你想動態加載對象呢?想象一個對象有多個子對象的列表(它們都實現相同的接口)並且必須加載子對象的數據? – Martijn 2011-02-25 09:18:50

+0

@Martijn:解決這個問題的一個很好的方法是使用像NHibernate這樣的動態代理。然後,即使在加載子對象時,也不需要存儲庫。 – Marcus 2011-02-25 09:20:42

+0

但我想知道這一點,而不使用NHibernate。 – Martijn 2011-02-25 09:22:47