gpt4 book ai didi

c# - 具有通用存储库的 Activator.CreateInstance

转载 作者:太空狗 更新时间:2023-10-29 23:13:32 25 4
gpt4 key购买 nike

我正在尝试(我认为是)一个根据传递给方法的枚举创建存储库的工厂。看起来像这样:

存储库工厂

public class RepositoryFactory
{
public IRepository<IEntity> GetRepository(FormTypes formType)
{
// Represents the IRepository that should be created, based on the form type passed
var typeToCreate = formType.GetAttribute<EnumTypeAttribute>().Type;

// return an instance of the form type repository
IRepository<IEntity> type = Activator.CreateInstance(typeToCreate) as IRepository<IEntity>;

if (type != null)
return type;

throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType)));
}
}

IRepository

public interface IRepository <T>
where T : class, IEntity
{
bool Create(IEnumerable<T> entities);

IEnumerable<T> Read();

bool Update(IEnumerable<T> entities);

bool Delete(IEnumerable<T> entities);
}

表单类型

public enum FormTypes
{
[EnumType(typeof(Form64_9C2Repository))]
Form64_9C2,

[EnumType(typeof(Form64_9BaseRepository))]
Form64_9Base
}

枚举扩展

public static class EnumExtensions
{

/// <summary>
/// Get the Enum attribute
/// </summary>
/// <typeparam name="T">The attribute</typeparam>
/// <param name="enumValue">The enum</param>
/// <returns>The type to create</returns>
public static T GetAttribute<T>(this System.Enum enumValue)
where T : Attribute
{
FieldInfo field = enumValue.GetType().GetField(enumValue.ToString());
object[] attribs = field.GetCustomAttributes(typeof(T), false);
T result = default(T);

if (attribs.Length > 0)
{
result = attribs[0] as T;
}

return result;
}

}

Form64_9C2存储库

public class Form64_9C2Repository : IRepository<Form64_9C2>
{
public bool Create(IEnumerable<Form64_9C2> entities)
{
throw new NotImplementedException();
}

public bool Delete(IEnumerable<Form64_9C2> entities)
{
throw new NotImplementedException();
}

public IEnumerable<Form64_9C2> Read()
{
throw new NotImplementedException();
}

public bool Update(IEnumerable<Form64_9C2> entities)
{
throw new NotImplementedException();
}
}

实体

public interface IEntity { }

Form64_9C2( stub )

public class Form64_9C2 : IEntity { }

将其全部称为:

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Repository Factory Example \n\n");

Business.Factory.RepositoryFactory factory = new Business.Factory.RepositoryFactory();

// Get a 64 9C2 repository
var repo9c2 = factory.GetRepository(FormTypes.Form64_9C2);
Console.WriteLine(repo9c2);
}
}

我的问题是我的 type总是解析为 null .我期待得到 NotImplementedException , 但我得到的是 ArgumentException因为没有有效的 formType。

enter image description here

在实现 IRepository<T> 之前我的type/repository已成功创建(工作代码 here ),有什么想法吗?我才刚刚开始研究工厂、泛型等 - 所以如果我做错了什么,请提出建议!

最佳答案

您的代码无法正常工作的原因与此行无法编译的原因完全相同:

IRepository<IEntity> repo = new Form64_9C2Repository();

基本上IRepository<IEntity>IRepository<Form64_9C2> 不同即使Form64_9C2工具 IEntity .

如果 T 这可能有效IRepository 上的通用参数界面是 covariant :

public interface IRepository<out T> where T : class, IEntity
{
IEnumerable<T> Read();
}

但不幸的是,这意味着它只能作为方法的返回类型出现,而不能作为参数出现。这对你的 Update 是不行的, DeleteCreate方法。您当然可以定义这样的结构:

public interface IReadonlyRepository<out T> where T : class, IEntity
{
IEnumerable<T> Read();
}

public interface IRepository<T>: IReadonlyRepository<T> where T : class, IEntity
{
bool Update(IEnumerable<T> entities);
bool Delete(IEnumerable<T> entities);
bool Create(IEnumerable<T> entities);
}

并拥有您的 GetRepository方法返回 IReadonlyRepository<IEntity> .

如果这对您不起作用,您将需要一个额外的参数来指定具体的实体类型,以便您执行正确的转换:

    public IRepository<TEntity> GetRepository<TEntity>(FormTypes formType) where TEntity: class, IEntity
{
// Represents the IRepository that should be created, based on the form type passed
var typeToCreate = formType.GetAttribute<EnumTypeAttribute>().Type;

// return an instance of the form type repository
IRepository<TEntity> type = Activator.CreateInstance(typeToCreate) as IRepository<TEntity>;

if (type != null)
return type;

throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType)));
}
}

并且在调用时除了指定存储库类型之外还需要指定实体类型:

var repo9c2 = factory.GetRepository<Form64_9C2>(FormTypes.Form64_9C2);

关于c# - 具有通用存储库的 Activator.CreateInstance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34596035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com