我在一个解决方案中有一个Web项目和一个类库项目。类库项目包含所有非标识数据的模型。我创建了一个验证器类来验证表中的唯一性(类别)。当我将验证器类放入类库项目时,它无法从Web项目访问上下文(RecipeContext)。如果我尝试将验证器类放入Web应用程序,我会收到“类型或命名空间名称”的错误 无法找到CategoryValidator''。
这是CategoryValidator类
namespace Spicy.Entities.Validators
{
public class CategoryValidator : AbstractValidator<Category>
{
public CategoryValidator()
{
RuleFor(x => x.Name).NotNull().WithMessage("Category Name is required.").Must(UniqueName).WithMessage("This category name already exists.");
}
private bool UniqueName(Category category, string name)
{
using (RecipeContext db = new RecipeContext())
{
var dbCategory = db.Categories
.Where(x => x.Name.ToLower() == name.ToLower())
.SingleOrDefault();
if (dbCategory == null)
return true;
return dbCategory.ID == category.ID;
}
}
}
}
这是类别模型
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Spicy.Entities
{
[Validator(typeof(CategoryValidator))]
public class Category
{
public int ID { get; set; }
[StringLength(20, ErrorMessage = "Category cannot be longer than 20 characters")]
[Required]
public string Name { get; set; }
[Required]
[DisplayName("User Name")]
[StringLength(20, ErrorMessage = "User Name cannot be longer than 20 characters")]
public string UserName { get; set; }
public virtual ICollection<Recipe> Recipes { get; set; }
}
}
这是global.asax代码
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
FluentValidationModelValidatorProvider.Configure();
}
}
我应该在哪里放置验证器类,如何解决我遇到的问题?
帮助。
答案 0 :(得分:1)
简单的解决方案(不是最好的): 在验证器中注入RecipeContext,放在Web
中代码:
public class CategoryValidator : AbstractValidator<Category>
{
RecipeContext _db;
public CategoryValidator(RecipeContext db)
{
_db = db;
RuleFor(x => x.Name).NotNull().WithMessage("Category Name is required.").Must(UniqueName).WithMessage("This category name already exists.");
}
}
与DDD对齐的高级解决方案:
YourCompany.Domain(不依赖于db或web)
YourCompany.DataAccess.EF
YourCompany.DataAccess.MongoDB(例如)
YourCompany.Web
域中的代码:
public interface ICategoryRepository
{
bool ContainsCategory(string name);
Category GetById(int id);
// other db methods for example
IEnumerable<Category> GetAll();
void Add(Category entity);
}
public class CategoryValidator : AbstractValidator<Category>
{
ICategoryRepository _categoryRepository;
public CategoryValidator(ICategoryRepository categoryRepository)
{
_categoryRepository = categoryRepository;
RuleFor(x => x.Name).NotNull().WithMessage("Category Name is required.").Must(UniqueName).WithMessage("This category name already exists.");
}
private bool UniqueName(Category category, string name)
{
return !_categoryRepository.Contains(name);
}
}
YourCompany.DataAccess.EF中的代码:
public class CategoryRepositoryEF
{
RecipeContext _db;
public CategoryRepository(RecipeContext db)
{
_db = db;
}
bool ContainsCategory(string name)
{
using (RecipeContext db = new RecipeContext())
{
var dbCategory = db.Categories
.Where(x => x.Name.ToLower() == name.ToLower())
.SingleOrDefault();
if (dbCategory == null)
return true;
return dbCategory.ID == category.ID;
}
}
}
网络代码:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<RecipeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// Register application services.
services.AddScoped<ICategoryRepository, CategoryRepositoryEF>();
}