我想在EF验证框架之上实现通用实体验证机制。我所做的是使用单个UPDATE public."mytable" SET alias='{a, b}' WHERE id='myid'
方法创建了一个通用接口,该接口将由不同的实体验证器实现。然后,我使用服务定位器模式实例化EF ofd.Filter = "CSV files (*.csv)|*.csv";
方法重写内的相关具体验证器实现。这是我的实现:
Validator界面
Validate()
验证器实施
ValidateEntity
服务定位器(验证定位器)
public interface IEntityValidator<T>
{
DbEntityValidationResult ValidateEntity(T entity);
}
ClientContext中的ValidateEntity内部方法
public class BranchValidator<Branch>: IEntityValidator<Branch>
{
ClientContext clientContext;
public BranchValidator(ClientContext clientContext)
{
this.clientContext = clientContext;
}
public DbEntityValidationResult ValidateEntity(Branch entity)
{
throw new NotImplementedException();
}
}
我在public static class ValidatorLocator<T>
{
public static IEntityValidator<T> validatorObject;
public static IEntityValidator<T> GetValidator(string entityType, ClientContext clientContext)
{
switch (entityType)
{
case "User":
validatorObject = new UserValidator<T>(clientContext);
break;
case "Branch":
validatorObject = new BranchValidator<T>(clientContext);
break;
default:
validatorObject = null;
break;
}
return validatorObject;
}
public static void Validate(T obj)
{
validatorObject.ValidateEntity(obj);
}
}
方法中遇到编译器错误-在下一行:
public partial class ClientContext : DbContext
{
public ClientContext(string connectionString)
: base(connectionString)
{
}
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
var entityName = entityEntry.Entity.GetType().FullName;
IEntityValidator<T> validatorObj = (T)ValidatorLocator.GetValidator(entityName, this);
return base.ValidateEntity(entityEntry, items);
}
}
错误提示:使用通用类型'ValidatorLocator'需要1个类型参数
返回我的泛型类型的具体实例的正确方法是什么?
答案 0 :(得分:0)
您可以使用诸如依赖项注入容器之类的东西:
public class ClientContext { }
public interface IEntityValidator<T> { }
public class Branch { }
public class BranchValidator : IEntityValidator<Branch>
{
public BranchValidator(ClientContext clientContext)
{
Console.WriteLine("Creating a BranchValidator with context {0}", clientContext);
}
}
public class Other { }
public class OtherValidator : IEntityValidator<Other> { }
public static class ValidatorLocator
{
private static readonly Dictionary<Type, Type> ValidatorContainer
= new Dictionary<Type, Type>();
/// <summary>
/// Use this method to register the validator class for an entity type.
/// It should have a constructor with ClientContext parameter
/// </summary>
public static void RegisterValidator<TEntity,TEntityValidator>()
where TEntityValidator : IEntityValidator<TEntity>
{
Console.WriteLine("=== RegisterValidator ===");
Console.WriteLine("Registering {0} to validate {1}:",
typeof(TEntityValidator), typeof(TEntity));
ValidatorContainer.Add(typeof(TEntity), typeof(TEntityValidator));
Console.WriteLine(" Checking constructor with ClientContext parameter");
var ctorParamTypes = new[] {typeof(ClientContext)};
var validatorCtor = typeof(TEntityValidator).GetConstructor(ctorParamTypes);
if (validatorCtor == null)
Console.WriteLine(" Couldn't find the constructor!!");
else
Console.WriteLine(" Successfully registered!");
}
public static IEntityValidator<TEntity> GetValidator<TEntity>(ClientContext clientContext)
{
Console.WriteLine("=== GetValidator ===");
Console.WriteLine("Getting validator for {0}", typeof(TEntity));
var validatorType = ValidatorContainer[typeof(TEntity)];
Console.WriteLine(" Looking for the constructor");
var ctorParamTypes = new[] {typeof(ClientContext)};
var validatorCtor = validatorType.GetConstructor(ctorParamTypes);
Console.WriteLine(" Constructor found");
var ctorParams = new[] {clientContext};
Console.WriteLine(" Creating validator");
var validator = validatorCtor.Invoke(ctorParams);
Console.WriteLine(" Succesfully created");
return (IEntityValidator<TEntity>)validator;
}
}
要使用它,必须为每种实体类型注册验证器类,然后才能找到服务构造函数并调用它。此技术有多种变体:例如,您可以注册每个验证器的单例实例并重用它,而不用寻找构造函数并在每次使用时调用它。
注意:很显然,Console.WriteLine
在这里可以查看正在发生的事情,但在实际实现中不是必需的
用法示例:
class Program
{
static void Main(string[] args)
{
ValidatorLocator.RegisterValidator<Branch,BranchValidator>();
ValidatorLocator.RegisterValidator<Other,OtherValidator>();
var clientContex = new ClientContext();
ValidatorLocator.GetValidator<Branch>(clientContext);
Console.WriteLine("Press a key to exit!!");
Console.ReadKey();
}
}