Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DI和存储库模式_C#_Design Patterns_Dependency Injection_Inversion Of Control_Repository Pattern - Fatal编程技术网

C# DI和存储库模式

C# DI和存储库模式,c#,design-patterns,dependency-injection,inversion-of-control,repository-pattern,C#,Design Patterns,Dependency Injection,Inversion Of Control,Repository Pattern,目前,我的代码与此类似(缩短只是为了说明一点): 达尔 存储库界面 public interface IRepository<TEntity, in TKey> { IList<TEntity> GetAll(); TEntity Get(TKey id); TEntity Add(TEntity item); TEntity Update(TEntity item); bool Remove(TKey id); } 当我阅读时开

目前,我的代码与此类似(缩短只是为了说明一点):

达尔 存储库界面

public interface IRepository<TEntity, in TKey>
{
    IList<TEntity> GetAll();
    TEntity Get(TKey id);
    TEntity Add(TEntity item);
    TEntity Update(TEntity item);
    bool Remove(TKey id);
}
当我阅读时开始产生困惑,作者说使用如下代码:

IContactsRepository repo = ResolveRepository<IContactsRepository>();  
IContactsRepository repo=ResolveRepository();
是一种糟糕的技术,它是反模式的,应该在代码的根注入所有内容。我不知道如何使用存储库模式来实现这一点。我正在使用WCF消费这个。那么,从WCF中的第一个调用开始,我到底该如何注入所有内容呢?我搞不懂。我错过了什么


最后一件事,在这种情况下,WCF是最后一层,它应该只知道它前面的层,即BLL层。如果我要实现该博客作者建议的任何东西,我会让WCF层意识到DAL层,这不是很糟糕的做法吗?如果我错了,请纠正我。

您需要确定适合用作合成根的接缝

对于WCF,您需要具有创造性—您必须创建一个自定义的
ServiceHostFactory
,以截取组成对象根的正确位置

例如,请参阅Mark Seemann(《.Net中的依赖注入》一书的作者),我认为这本书非常有用

许多免费DI容器为WCF提供现成的支持,这可能是最好的方法

我真的不能高度推荐希曼的书——它涉及了很多细节


您可能也会觉得有趣。

您需要使用构造函数注入,然后在中组合对象

使用构造函数注入时,通过构造函数注入依赖项,因此类的外观如下所示:

 var _contacts = new Contacts();
 var contact = _contacts.GetByEmployeeId("C1112", ContactType.Emergency);
public class BaseRepository
{
    protected readonly DbContext _dbContext;

    //...
    public BaseRepository(DbContext context)
    {
        _dbContext = context;
    }
    //...
}

public class ContactsRepository : BaseEFRepository<Contact, long>, IContactsRepository
{
    //...
    public ContactsRepository(DbContext context)
        :base(context)
    {

    }
    //...
}

public class Contacts
{
    private readonly IContactsRepository m_ContactsRepository;

    public Contacts(IContactsRepository contacts_repository)
    {
        m_ContactsRepository = contacts_repository;
    }

    public Contact Get(long id)
    {
        var contact = m_ContactsRepository.Get(id);
        return contact;
    }
    //...
}

在IIS中承载的WCF应用程序中,组合根是自定义的
ServiceHostFactory
。提供了有关如何执行此操作的更多详细信息。

@Matthew的帖子应该可以回答您的问题。然而,我想提到一件事,我在你的代码中注意到了这个问题。您不应该尝试手动解决依赖关系,但它应该由容器注入。我已修改您的代码以显示此行为:

public class Contacts
{
    private IContactsRepository repo;
    public Contacts(IContactsRepository injectedContactsRepository)
    {
        repo = injectedContactsRepository;
    }


    public Contact Get(long id)
    {
        var contact = repo.Get(id);
        return contact;
    }

//and other methods definitions...
}

那么,您的应用程序是WCF应用程序?它是托管在IIS中还是自托管?在控制台应用程序中?或者在windows服务中?请原谅我的无知,但这不会使WCF层意识到DAL层,而它应该只意识到BLL层。。。如果我错了,请纠正我。WCF宿主代码必须了解所有内容,是的。它是组成根。但是,服务层(例如<代码>联系人< /Class >类)不需要了解所有的内容。您应该将WCF托管逻辑视为系统的独立部分,并将其称为“组成根”。这与包含WCF服务本身的服务层完全不同。我会深入研究这个问题。不是一个程序员(我)和试图正确编程是一个痛苦的屁股。。我应该改变我的爱好:/请原谅我的无知,但这不会让WCF层意识到DAL层,而它应该只意识到BLL层。。。如果我错了,请纠正我。@HeidelBerGensis WCF层是一个用作合成根的seam,其中一些代码可以识别多个层。这是可以的,因为它只是连接DI容器的地方。
IContactsRepository repo = ResolveRepository<IContactsRepository>();  
public class BaseRepository
{
    protected readonly DbContext _dbContext;

    //...
    public BaseRepository(DbContext context)
    {
        _dbContext = context;
    }
    //...
}

public class ContactsRepository : BaseEFRepository<Contact, long>, IContactsRepository
{
    //...
    public ContactsRepository(DbContext context)
        :base(context)
    {

    }
    //...
}

public class Contacts
{
    private readonly IContactsRepository m_ContactsRepository;

    public Contacts(IContactsRepository contacts_repository)
    {
        m_ContactsRepository = contacts_repository;
    }

    public Contact Get(long id)
    {
        var contact = m_ContactsRepository.Get(id);
        return contact;
    }
    //...
}
var context = new MyDB();

context.Configuration.ProxyCreationEnabled = false;

context.Configuration.LazyLoadingEnabled = false;

var contacts = new Contacts(new ContactsRepository(context));
public class Contacts
{
    private IContactsRepository repo;
    public Contacts(IContactsRepository injectedContactsRepository)
    {
        repo = injectedContactsRepository;
    }


    public Contact Get(long id)
    {
        var contact = repo.Get(id);
        return contact;
    }

//and other methods definitions...
}