基于类型变量实例不同存储库的策略模式
我正在从事一个维基项目。 MVC3 + EF4 代码优先。
我的模型中的所有类都继承自主“EditBase”类。这可确保它们都有 ID、用户名和创建日期。它还帮助我为基本 CRUD 创建通用存储库。
我希望定义一个名为 AbuseReport 的新实体来处理不正确/不准确内容的标记:
public class AbuseReport : EditBase
{
public DateTime DateReported { get; set; }
public string EntityType { get; set; }
public int EntityId { get; set; }
public int ReportTypeId { get; set; }
public ReportType ReportType
{
get { return (ReportType) this.ReportTypeId; }
set { this.ReportTypeId = (int) value; }
}
public string Description { get; set; }
}
从 AbuseReport 对象上的信息开始检索存储在数据库中的实体的最简单方法是什么?我无法使用外键,因为报告可以引用项目中的任何实体。
我需要这样调用:
Type modelType;
entityDictionary.TryGetValue(entityName, out modelType);
var rep = new Repository<modelType>();
I'm working on a wiki project. MVC3 + EF4 Code First.
All classes from my model inherit from a main "EditBase" class. This assures that they all have ID, Username and CreatedDate. It also helps me create a generic Repository for basic CRUDs.
I wish to define a new entity called AbuseReport to handle flagging of incorrect/innacurate content:
public class AbuseReport : EditBase
{
public DateTime DateReported { get; set; }
public string EntityType { get; set; }
public int EntityId { get; set; }
public int ReportTypeId { get; set; }
public ReportType ReportType
{
get { return (ReportType) this.ReportTypeId; }
set { this.ReportTypeId = (int) value; }
}
public string Description { get; set; }
}
What would be the easiest way to retrieve an entity stored on the database starting from the information on a AbuseReport object? I can't use foreign keys because the report can refer to any entity on the project.
I would need to call something like this:
Type modelType;
entityDictionary.TryGetValue(entityName, out modelType);
var rep = new Repository<modelType>();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会将所有模型类型存储在同一个存储库中。存储库密钥必须包含模型的类型及其 ID。我使用本地类
RepositoryKey
来实现此目的:I would store all the model types in the same repository. The repository key will have to contain the type of the model as well as its ID. I use the local class
RepositoryKey
for this purpouse:我不完全确定我明白你在做什么,但我相信问题是如何采用开放泛型类型并将其设为封闭泛型类型。
如果是这种情况,请尝试这个反射魔法:
或者如果您使用容器或类似的东西,请从容器的 MakeGenericType 调用中解析生成的封闭泛型类型,而不是使用 Activator.CreateInstance。不管怎样,你最终都会得到一个你想要的实例。
这符合您正在寻找的内容吗?
编辑:
为了回答 Olivier Jacot-Descombe 的问题,这里有一些想法和代码:
理想情况下,我会使用您选择的 ioc 容器的一些内置功能或类似此反射代码的东西来注册开放泛型类型容器或某些选择的封闭类型(容器的功能各不相同)。然后,当使用泛型类型作为依赖项时,您可以在了解打算用作泛型参数的类型的情况下执行此操作,并从容器中解析已知类型(在大多数情况下,您可能确切地知道在查找时要查找的类型)你实际使用它)。如果由于不使用容器或容器功能有限而无法选择该选项,并且情况略有不同,并且您要求提供在编译时知道的泛型类型参数,则可以使用如下方法
:确实存在像问题一样未知的情况,这是一个棘手的问题。我想到的一个想法是拥有一个非泛型存储库类(或者任何适合此模式的类型),并将泛型类型子类设为非泛型(但如果方法依赖于泛型类型,则它将不起作用,他们可能会这样做)并将结果转换为基本的非泛型类型。可能很少有情况会真正起作用。
另一个答案可能是使类成为非泛型,而只具有方法的泛型参数。这是我对我的存储库所做的事情,我认为无论如何这是一种更好的方法,并且只需具有一种存储库类型而不是与持久类一样多的存储库类型来简化依赖关系。
i'm not completely sure i understand what you are after, but i believe the question is how to take an open generic type and make it a closed generic type.
if that's the case, try this reflection magic:
or if you are using a container or something along those lines, resolve the resulting closed generic type from the MakeGenericType call from the container rather than using Activator.CreateInstance. either way, you should wind up with an instance of what you want.
is that along the lines of what you are looking for?
EDIT:
in response to the question from Olivier Jacot-Descombes, here are some thoughts and code:
ideally, i'd use some of the built in capabilities of your ioc container of choice or something like this reflection code to register the open generic type with the container or some select closed types (capabilities of containers vary). then when using the generic type as a dependency, you can do so with knowledge of the type you intend to use as the generic parameter and resolve a known type from the container (in most cases you probably know exactly what type you are looking for when you actually use it). if that's not an option because of not using a container or having limited container capabilities, and the situation is a little different and you are asking for a generic type parameter you know at compile time, you could have a method something like this:
if it truly is a situation like the question where that is not known, it's a tough question. one thought that comes to mind is to have a nongeneric Repository class (or whatever your type is that fits this pattern) and make the one with the generic type subclass the nongeneric (but it won't work if the methods depend on the generic type, which they probably do) and cast the result to the base, nongeneric type. probably very few situations where that would actually work.
another answer might be to make the class nongeneric and instead just have generic parameters for the methods. this is something i have done with my repositories and i think it's a better way to do it anyway and simplifies dependencies with just having one repository type instead of as many repository types as you have persistent classes.