C# 为什么要将存储库用作属性?

C# 为什么要将存储库用作属性?,c#,repository,C#,Repository,我正在阅读存储库的使用情况。有时我看到存储库是实体的属性。我想知道赞成和反对的是什么 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) {

我正在阅读存储库的使用情况。有时我看到存储库是实体的属性。我想知道赞成和反对的是什么

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);
   }
}
公共接口IRepository
{
T GetById(int-id);
无效更新(T);
}
公共类FooRepository:IRepository
{
公共Foo GetById(inti)
{/*代码..*/}
无效更新(Foo)
{/*代码..*/}
}
公开课Foo
{
公共IRepository存储库{get;set;}
公共无效更新()
{
更新(本);
}
}
为什么要用这个方法?分开使用存储库和实体对象不是更有意义吗?这样实体对象就不知道任何存储库了

编辑:

但如果有一个主对象和不同的子对象,该怎么办

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;}
}
public类main对象
{
公共int Id{get;set;}
公共列表子对象{get;}
}
公共接口是子对象
{
}
公共类子对象A:ISubObject
{
公共字符串SomeProperty{get;set;}
公共int Id{get;set;}
public int MainObjectId{get;set;}
}
公共类子对象B:ISubObject
{
公共字符串另一个属性{get;set;}
公共int Id{get;set;}
public int MainObjectId{get;set;}
}

因此,SubObjectA和SubObjectB是不同的类型,但是实现了ISubject接口。主对象具有这些子对象的列表。每个子对象都有自己的存储库。如何加载子对象?

我不会使用此方法。更新自己不是Foo的责任,而是存储库的责任。如果您正在应用持久无知模式

此代码是一种气味:

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

它除了将调用转发到存储库之外什么都不做。

我不会使用这种方法。更新自己不是Foo的责任,而是存储库的责任。如果您正在应用持久无知模式

此代码是一种气味:

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

它除了将调用转发到存储库之外什么都不做。

您可以将它与Spring一起使用

或者另一个依赖注入util来动态加载对象。只要它实现了接口,它就会以同样的方式工作。面向方面编程

看看下面的帖子


您可以将其与弹簧一起使用

或者另一个依赖注入util来动态加载对象。只要它实现了接口,它就会以同样的方式工作。面向方面编程

看看下面的帖子


一些实体实现需要访问创建它们的上下文,例如实现延迟加载。考虑以下事项:

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

interface IMyEntityRepository
{
    ...
}
类MyEntity
{
公共虚拟IEnumerable标记{get;private set;}
}
界面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 { }
内部类MyLazyEntity:MyEntity
{
公共MyLazyEntity(MyLazyEntityRepository存储库)
{
this.Repository=Repository;
}
公共覆盖IEnumerable标记
{
得到
{
返回this.Repository.LoadTagsForentyFromXML(this.Id);
}
}
}
类MyLazyEntityRepository:IMyEntityRepository{}

我想说的是,在从实体派生的类中保留对源存储库的引用是可以的,另一方面,基本实体类不应该了解存储库。

一些实体实现需要访问创建它们的上下文,例如实现延迟加载。考虑以下事项:

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

interface IMyEntityRepository
{
    ...
}
类MyEntity
{
公共虚拟IEnumerable标记{get;private set;}
}
界面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 { }
内部类MyLazyEntity:MyEntity
{
公共MyLazyEntity(MyLazyEntityRepository存储库)
{
this.Repository=Repository;
}
公共覆盖IEnumerable标记
{
得到
{
返回this.Repository.LoadTagsForentyFromXML(this.Id);
}
}
}
类MyLazyEntityRepository:IMyEntityRepository{}

我想说的是,在从实体派生的类中保留对源存储库的引用是很好的,另一方面,基本实体类不应该了解存储库。

但是如果要动态加载对象呢?假设一个对象有一个多个子对象的列表(所有子对象都实现了相同的接口),并且必须加载子对象的数据?@Martijn:一个很好的解决方法是使用像NHibernate这样的动态代理。那么你根本不需要存储库,即使在加载子对象时也是如此。但我想知道这一点,而不使用NHibernate。你不需要NHibernate,我只是说NH是如何做到的。动态代理。加载子对象的另一种方法是将其移动到存储库中。GetSubObjects(int-parentObjectId);。甚至在获取根聚合时让存储库填充整个对象图。很抱歉,我读得不够好。我将阅读动态代理。听起来很有趣。但是如果你想动态加载对象呢?假设一个对象有一个多个子对象的列表(所有子对象都实现了相同的接口),并且必须加载子对象的数据?@Martijn:一个很好的解决方法是使用像NHibernate这样的动态代理。那么你根本不需要存储库,即使在加载子对象时也是如此。但我想知道这一点,而不使用NHibernate。你不需要NHibernate,我只是说NH是如何做到的。动态代理。加载子对象的另一种方法是将其移动到存储库中。GetSubObjects(int-parentObjectId);。甚至在获取根聚合时让存储库填充整个对象图