“重命名” C#中接口的继承方法

发布于 2024-07-26 11:16:51 字数 2628 浏览 3 评论 0原文

我试图在开发 ASP.NET MVC 应用程序(使用 .NET 3.5、ASP.NET MVC 1.0 和实体框架)时理解存储库模式。 我已经足够了解依赖注入并使用一个控制器和一种实体类型进行所有工作,但现在我已经达到了实现对不同类型之间关系的支持的程度,但我陷入了困境。

在我见过的所有示例中,存储库接口的名称类似于 IContactsRepository,并且包含仅与 Contact 项相关的 (CRUD) 方法。 我想实现 Contacts 的分组,因此我有一个名为 Group 的实体类型,以及一个用于处理组上的 (CRUD) 操作的 IGroupRepository 接口。

  • 涉及多个实体类型的方法属于哪里(在本例中,例如方法 AddToGroup,它将 Contact 添加到 Group)?

我尝试为存储库创建更大的继承结构,在其中创建了以下接口:

ITypedRepository<T>
{
    IEnumerable<T> GetAll();
    T Get(int id);
    bool Add(T newObj);
    bool Edit(T editedObj);
    bool Delete(int id);
}

IContactsRepository : ITypedRepository<Contact> { }

IGroupsRepository : ITypedRepository<Group> {
    bool AddToGroup(int contactId, int groupId);
}

IRepository : IContactsRepository, IGroupsRepository

然后,我尝试创建一个继承 IRepository 的主存储库,如下所示:

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        throw new NotImplementedException();
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        throw new NotImplementedException();
    }
    // Etc. All methods were generated by hitting [Ctrl]+[.] with the cursor on
    // the interface inheritance reference to IRepository and selecting
    // "Explicitly implement IRepository"
}

一旦我尝试调用其中之一使用此代码从我的控制器存储库中的方法,

var contacts = _repository.Get();

我收到一条关于通过 IContactsRepository 继承的 Get()Get< 继承的 Get() 之间不明确的构建错误消息通过 IGroupsRepository 提供的 ;Group>()。 我知道这是不允许的,因为 IRepository 继承具有不同类型的相同通用接口(请参阅链接文章中的示例 5)。

  • 现在,由于我通过其他接口继承,我是否有机会“覆盖这些方法的名称”,例如如下所示?

    IContactsRepository : ITypedRepository; 
      { 
          IEnumerable<联系人>   GetContacts = ITypedRepository.Get(); 
          ... 
      } 
      

这样,我就可以从 IRepository.Getcontacts 访问它,没有任何歧义。 有可能吗,或者有什么解决方法可以解决这个问题吗?

还有一个新问题,需要澄清:

  • 是否要在控制器的调用中指定我想要的 Get() 方法?

  • 解决我的初始问题的最佳方法是什么 - 需要一个处理很多事情的存储库,而不仅仅是一种实体类型?

编辑:添加了Repository类的代码示例以及来自Controller的调用。

I'm trying to understand the Repository Pattern, while developing an ASP.NET MVC application (using .NET 3.5, ASP.NET MVC 1.0 and Entity Framework). I've gotten far enough to get the dependency injection and all working with one Controller and one Entity type, but now I've gotten as far as to implementing support for a relation between different types, and I'm stuck.

In all examples I've seen, the repository interface is called something like IContactsRepository, and contains (CRUD) methods that are concerned with Contact items only. I want to implement grouping of Contacts, so I have an entity type called Group, and an IGroupRepository interface for handling (CRUD) operations on groups.

  • Where does a method belong that is concerned with more than one entity type (in this case for example the method AddToGroup, that adds a Contact to a Group)?

I made an attempt at a larger inheritance structure for repositories, where I created the following interfaces:

ITypedRepository<T>
{
    IEnumerable<T> GetAll();
    T Get(int id);
    bool Add(T newObj);
    bool Edit(T editedObj);
    bool Delete(int id);
}

IContactsRepository : ITypedRepository<Contact> { }

IGroupsRepository : ITypedRepository<Group> {
    bool AddToGroup(int contactId, int groupId);
}

IRepository : IContactsRepository, IGroupsRepository

I then tried to create a master repository that inherits IRepository, as follows:

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        throw new NotImplementedException();
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        throw new NotImplementedException();
    }
    // Etc. All methods were generated by hitting [Ctrl]+[.] with the cursor on
    // the interface inheritance reference to IRepository and selecting
    // "Explicitly implement IRepository"
}

As soon as I try to call one of the methods in the Repository from my Controller with this code

var contacts = _repository.Get();

I get a build error message about ambiguity between Get<Contact>() that was inherited via IContactsRepository and Get<Group>() that came via IGroupsRepository. I have understood that this is not allowed because the IRepository inherits the same generic interface with different types (see example 5 in the linked article).

  • Now, since I inherit via other interfaces, is there any chance I could "override the names" of these methods, for example like below?

    IContactsRepository : ITypedRepository<Contact>
    {
        IEnumerable<Contact> GetContacts = ITypedRepository<Contact>.Get();
        ...
    }
    

That way, I can access it from IRepository.Getcontacts without any ambiguity. Is it possible, or is there any workaround to this problem?

And a new question, for clarification:

  • Is there anyway to specify in the call from the controller which of the Get() methods I want?

  • What is the best way to tackle my initial problem - the need of a repository that handles a lot of things, instead of just one entity type?

EDIT: Added code example of Repository class and call from Controller.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

別甾虛僞 2024-08-02 11:16:51

我认为你不需要所有这些复杂性。 当您将联系人添加到组时,您正在更改该组。 我假设您有一组关于团体课程的联系人。 将联系人添加到群组后,您只需保存该群组即可。 那么,您真的需要 AddContactToGroup 方法吗?只需 Group 存储库接口上的 Save 方法即可完成相同的工作。 此外,您不需要为 Group 上的每个新关系属性使用新方法。

对于Save方法本身的实现,如果你使用NHibernate,你只需调用相关方法即可。

I think you don't need all this complexity. When you add a contact to a group you are changing the group. I assume you have a collection of contacts on Group class. After adding a contact into a group, simply you need to save the group. So do you really need a AddContactToGroup method, just a Save method on Group repository interface would do the same job. Also you don't need a new method for every new relational property on Group.

For the implementation of the Save method itself, if you use NHibernate, only thing you need to do is to call relevant method.

红焚 2024-08-02 11:16:51

除了 CRUD 方法之外,您的 IGroupRepository 上可能还会有专门的方法:

IGroupRepository : ITypedRepository<Group>
{
    bool AddContactToGroup(Group g, Contact C);
}

You will probably have specialized methods on your IGroupRepository in addition to the CRUD methods:

IGroupRepository : ITypedRepository<Group>
{
    bool AddContactToGroup(Group g, Contact C);
}
樱花落人离去 2024-08-02 11:16:51

添加具有调用显式实现的明确名称的方法:

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        // Return something
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        // Return something
    }

    public IEnumerable<Contact> GetContacts()
    {
        return (this as IRepository<Contact>).Get();
    }

    public IEnumerable<Group> GetGroups()
    {
        return (this as IRepository<Group>).Get();
    }
}

Add methods with non-ambiguous names that call the explicit implementations :

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        // Return something
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        // Return something
    }

    public IEnumerable<Contact> GetContacts()
    {
        return (this as IRepository<Contact>).Get();
    }

    public IEnumerable<Group> GetGroups()
    {
        return (this as IRepository<Group>).Get();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文