นี่คือโซลูชันและโครงการของฉัน:
- ร้านหนังสือ (โซลูชัน)
- BookStore.Coupler (โครงการ)
- Bootstrapper.cs
- BookStore.Domain (โครงการ)
- CreateBookCommandValidator.cs
- CompositeValidator.cs
- IValidate.cs
- IValidator.cs
- ICommandHandler.cs
- BookStore.Infrastructure (โครงการ)
- CreateBookCommandHandler.cs
- ValidationCommandHandlerDecorator.cs
- BookStore.Web (โครงการ)
- Global.asax
- BookStore.BatchProcesses (โครงการ)
- Program.cs
- BookStore.Coupler (โครงการ)
Bootstrapper.cs :
public static class Bootstrapper.cs
{
// I'm using SimpleInjector as my DI Container
public static void Initialize(Container container)
{
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>), typeof(CreateBookCommandHandler).Assembly);
container.RegisterDecorator(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>));
container.RegisterManyForOpenGeneric(typeof(IValidate<>),
AccessibilityOption.PublicTypesOnly,
(serviceType, implTypes) => container.RegisterAll(serviceType, implTypes),
typeof(IValidate<>).Assembly);
container.RegisterSingleOpenGeneric(typeof(IValidator<>), typeof(CompositeValidator<>));
}
}
CreateBookCommandValidator.cs
public class CreateBookCommandValidator : IValidate<CreateBookCommand>
{
public IEnumerable<IValidationResult> Validate(CreateBookCommand book)
{
if (book.Author == "Evan")
{
yield return new ValidationResult<CreateBookCommand>("Evan cannot be the Author!", p => p.Author);
}
if (book.Price < 0)
{
yield return new ValidationResult<CreateBookCommand>("The price can not be less than zero", p => p.Price);
}
}
}
CompositeValidator.cs
public class CompositeValidator<T> : IValidator<T>
{
private readonly IEnumerable<IValidate<T>> validators;
public CompositeValidator(IEnumerable<IValidate<T>> validators)
{
this.validators = validators;
}
public IEnumerable<IValidationResult> Validate(T instance)
{
var allResults = new List<IValidationResult>();
foreach (var validator in this.validators)
{
var results = validator.Validate(instance);
allResults.AddRange(results);
}
return allResults;
}
}
IValidate.cs
public interface IValidate<T>
{
IEnumerable<IValidationResult> Validate(T instance);
}
IValidator.cs
public interface IValidator<T>
{
IEnumerable<IValidationResult> Validate(T instance);
}
ICommandHandler.cs
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
CreateBookCommandHandler.cs
public class CreateBookCommandHandler : ICommandHandler<CreateBookCommand>
{
private readonly IBookStore _bookStore;
public CreateBookCommandHandler(IBookStore bookStore)
{
_bookStore = bookStore;
}
public void Handle(CreateBookCommand command)
{
var book = new Book { Author = command.Author, Name = command.Name, Price = command.Price };
_bookStore.SaveBook(book);
}
}
ValidationCommandHandlerDecorator.cs
public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;
private readonly IValidator<TCommand> validator;
public ValidationCommandHandlerDecorator(ICommandHandler<TCommand> decorated, IValidator<TCommand> validator)
{
this.decorated = decorated;
this.validator = validator;
}
public void Handle(TCommand command)
{
var results = validator.Validate(command);
if (!results.IsValid())
{
throw new ValidationException(results);
}
decorated.Handle(command);
}
}
Global.asax
// inside App_Start()
var container = new Container();
Bootstrapper.Initialize(container);
// more MVC specific bootstrapping to the container. Like wiring up controllers, filters, etc..
Program.cs
// Pretty much the same as the Global.asax
ขออภัยสำหรับปัญหาการตั้งค่าที่ยาวนานฉันไม่มีวิธีที่ดีกว่าในการอธิบายเรื่องนี้นอกเหนือจากรายละเอียดปัญหาที่แท้จริงของฉัน
ฉันไม่ต้องการที่จะทำให้ public
CreateBookCommandValidator ฉันอยากจะเป็นinternal
แต่ถ้าฉันทำinternal
ฉันจะไม่สามารถลงทะเบียนกับ DI Container ของฉันได้ เหตุผลที่ฉันต้องการให้เป็นแบบภายในเพราะโครงการเดียวที่ควรมีแนวคิดเกี่ยวกับการทำให้เกิดผล IValidate <> ของฉันอยู่ในโครงการ BookStore.Domain โครงการอื่น ๆ เพียงแค่ต้องใช้ IValidator <> และ CompositeValidator ควรแก้ไขซึ่งจะตอบสนองการตรวจสอบทั้งหมด
ฉันจะใช้ Dependency Injection โดยไม่ทำลาย encapsulation ได้อย่างไร หรือฉันจะทำผิดทั้งหมดหรือเปล่า?