【发布时间】:2015-10-06 13:27:09
【问题描述】:
我正在使用存储库模式开发 C# MVC 应用程序。我使用 Unity 作为我的 IoC,以便在 MVC 应用程序中实现我的存储库。
我创建了以下泛型类型,目的是最大限度地减少整个应用程序中的代码复制。这是一个示例:
public abstract class GenericRepository<T, C> : IDisposable,IGenericRepository<T> where T : class where C : DbContext, new()
public async void AddObjectAsync<T>(T entity) where T : class
{
try
{
// Validate that that there is not an existing object in the database.
var x = _context.Entry(entity);
if (!Exists(entity))
{
_context.Set<T>().Add(entity); // Add the entry if it does not exist.
_context.SaveChanges();
}
else
{
UpdateObjectAsync(entity); // Update the entry if it did exist.
}
}
catch
{
throw;
}
这在我使用 TPC 或 TPH 策略时效果很好,但它不适用于 TPT 策略。一个例子:
public abstract class Component
{
[Key]
public Guid ComponentId { get; set; }
public string Manufacturer { get; set; }
}
public class SpecialComponent : Component
{
public string ExtraSpecialProperty { get; set; }
}
我在 ComponentRepository 中的实现:
public class ComponentRepository : GenericRepository<Component, HappyDbContext>, IComponentRepository
{
public async void AddComponentAsync<T>(T component) where T : class
{
try
{
if(component != null)
{
AddObjectAsync(component);
}
else
{
throw new ArgumentNullException();
}
}
catch (ArgumentNullException ex)
{
_logger.WriteErrorLogAsync(ex);
throw ex;
}
}
这个代码块的第一行是我遇到的问题。为了初始化 GenericRepository 类型,我需要为 T 插入一个类。在这种情况下,DbContext C 将始终相同,因此无需担心。
如何实现适用于继承类型的完全通用模式?如果是少量物品,那么我就不那么担心了,但是在这种情况下并非如此。我认为肯定有更好的方法来处理这个问题,所以我向大家征求意见。
【问题讨论】:
-
GenericRepository 类的
T参数和AddObjectAsync 的T参数是什么关系? -
在这种情况下您可以使用组合而不是继承吗?如果 ComponentRepository 注入了一个能够构造 GenericRepository 实例的专用工厂,那么
AddComponentAsync可以调用该工厂以根据提供给该方法的类型构造一个强泛型存储库。 -
对不起,我误读了您的评论。他们是一样的。如果我们传递实体“组件”,则 AddObjectAsync 将是
类型,并期望(组件实体)的方法参数。 -
@StriplingWarrior 这是一个非常有趣的建议,今晚我将对其进行调查,并让您知道它是否适用于我的模型。我正在想象某种基于服务的方法,这很可能是答案。如果我不是一个完整的新手,我可能会更快地告诉你!感谢您迄今为止的意见。
-
如果两个
T类型相同,则该方法不需要在该级别是通用的。public async void AddObjectAsync(T entity) {..}可以正常工作。
标签: c# asp.net-mvc entity-framework generics