我正在尝试(我认为)一个工厂,它根据传递给方法的枚举创建一个存储库.看起来像这样:
RepositoryFactory
public class RepositoryFactory { public IRepositoryGetRepository(FormTypes formType) { // Represents the IRepository that should be created, based on the form type passed var typeToCreate = formType.GetAttribute ().Type; // return an instance of the form type repository IRepository type = Activator.CreateInstance(typeToCreate) as IRepository ; if (type != null) return type; throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType))); } }
IRepository
public interface IRepositorywhere T : class, IEntity { bool Create(IEnumerable entities); IEnumerable Read(); bool Update(IEnumerable entities); bool Delete(IEnumerable entities); }
FormTypes
public enum FormTypes { [EnumType(typeof(Form64_9C2Repository))] Form64_9C2, [EnumType(typeof(Form64_9BaseRepository))] Form64_9Base }
EnumExtensions
public static class EnumExtensions { ////// Get the Enum attribute /// ///The attribute /// The enum ///The type to create public static T GetAttribute(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_9C2Repository
public class Form64_9C2Repository : IRepository{ public bool Create(IEnumerable entities) { throw new NotImplementedException(); } public bool Delete(IEnumerable entities) { throw new NotImplementedException(); } public IEnumerable Read() { throw new NotImplementedException(); } public bool Update(IEnumerable entities) { throw new NotImplementedException(); } }
IEntity
public interface IEntity { }
Form64_9C2(存根)
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.
在实现IRepository
我的type
/ repository
成功创建之前(这里的工作代码),任何想法?我只是开始玩工厂,仿制药等等 - 所以如果我做错了什么,请指教!
您的代码不能用于此行无法编译的完全相同的原因:
IRepositoryrepo = new Form64_9C2Repository();
即使是工具,基本上IRepository
也不一样.IRepository
Form64_9C2
IEntity
如果接口T
上的泛型参数IRepository
是covariant
:
public interface IRepositorywhere T : class, IEntity { IEnumerable Read(); }
但不幸的是,这意味着它只能作为方法的返回类型出现,而不是作为参数出现.对于你和方法来说Update
,这是不行的.你当然可以定义这样的结构:Delete
Create
public interface IReadonlyRepositorywhere T : class, IEntity { IEnumerable Read(); } public interface IRepository : IReadonlyRepository where T : class, IEntity { bool Update(IEnumerable entities); bool Delete(IEnumerable entities); bool Create(IEnumerable entities); }
让你的GetRepository
方法返回一个IReadonlyRepository
.
如果这对您不起作用,您将需要一个额外的参数来指定具体的实体类型,以便您执行正确的强制转换:
public IRepositoryGetRepository (FormTypes formType) where TEntity: class, IEntity { // Represents the IRepository that should be created, based on the form type passed var typeToCreate = formType.GetAttribute ().Type; // return an instance of the form type repository IRepository type = Activator.CreateInstance(typeToCreate) as IRepository ; if (type != null) return type; throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType))); } }
除了指定存储库类型之外,还需要指定实体类型:
var repo9c2 = factory.GetRepository(FormTypes.Form64_9C2);