Tôi có giao diện chung, có hai loại chung. Tôi muốn trang trí tất cả các phiên bản trả về, nhưng vì tôi không biết loại khi gọi EnrichWith, nó rõ ràng là không biên dịch. Tôi đã thử sử dụng EnrichWith overload quá tải trong ngữ cảnh, nghĩ rằng có lẽ tôi có thể lấy các kiểu generic được truyền vào và gọi Activator.CreateInstance, nhưng ngữ cảnh không có bất kỳ thông tin hữu ích nào khi gỡ lỗi và kiểm tra nó.Trang trí giao diện chung với Structuremap
Đây là những gì tôi có cho đến nay. Đây là giao diện chung của tôi:
public interface IServiceOperation<in TRequest, out TResponse> where TResponse : ServiceResult, new()
{
TResponse PerformService(TRequest validatedRequest);
}
Dưới đây là một việc thực hiện mẫu:
public class SignUpService : IServiceOperation<SignUpRequest, SignUpResult>
{
private readonly IUserRepository _userRepo;
public SignUpService(IUserRepository userRepo)
{
_userRepo = userRepo;
}
public SignUpResult PerformService(SignUpRequest validatedRequest)
{
var user = Mapper.Map<User>(validatedRequest);
user.MarkAsLoggedIn();
user.ChangePassword(validatedRequest.UnhashedPassword);
using(var transaction = _userRepo.BeginTransaction())
{
_userRepo.Save(user);
transaction.Commit();
}
return new SignUpResult();
}
}
Đây là trang trí của tôi, mà mất trong một dịch vụ khác cũng như:
public class ValidateServiceDecorator<TRequest, TResponse> : IServiceOperation<TRequest, TResponse> where TResponse : ServiceResult, new()
{
private readonly IServiceOperation<TRequest, TResponse> _serviceOperation;
private readonly IValidationService _validationService;
public ValidateServiceDecorator(IServiceOperation<TRequest, TResponse> serviceOperation,
IValidationService validationService)
{
_serviceOperation = serviceOperation;
_validationService = validationService;
}
public TResponse PerformService(TRequest request)
{
var response = new TResponse();
var validationResult = _validationService.Validate(request);
if (!validationResult.IsValid)
{
response.ValidationErrors = validationResult.ValidationErrors;
return response;
}
return _serviceOperation.PerformService(request);
}
Cuối cùng, đây là cách xa tôi đã nhận được trên container của tôi. Điều này rõ ràng không biên dịch, nhưng dòng EnrichWith cho thấy những gì tôi đang cố gắng để đạt được:
public class StructureMapServiceScanner : Registry
{
public StructureMapServiceScanner()
{
Scan(scanner =>
{
scanner.AssemblyContainingType(typeof (IServiceOperation<,>));
scanner.ConnectImplementationsToTypesClosing(typeof (IServiceOperation<,>));
});
For(typeof (IServiceOperation<,>))
.EnrichWith((ioc, original) => new ValidateServiceDecorator(original, ioc.GetInstance<IValidationService>()));
}
}
Và chỉ vì câu hỏi này cần một ít mã hơn, đây là thử nghiệm của tôi rằng tôi đang cố gắng để có được để vượt qua :
[TestClass]
public class StructureMapServiceScannerSpecs
{
[TestMethod]
public void Test()
{
ObjectFactory.Configure(cfg =>
{
cfg.AddRegistry<StructureMapServiceScanner>();
cfg.For<IUserRepository>().Use(new Mock<IUserRepository>().Object);
cfg.For<IValidationService>().Use(new Mock<IValidationService>().Object);
});
var service = ObjectFactory.GetInstance<IServiceOperation<SignUpRequest, SignUpResult>>();
service.ShouldNotBeNull();
service.ShouldBeType<ValidateServiceDecorator<SignUpRequest, SignUpResult>>();
}
}
Tôi cảm thấy đây là điều đơn giản và tôi thực sự thiếu thứ gì đó về cách sử dụng StructureMap. Tôi có thể tạo ra các phiên bản kiểu cụ thể cho tất cả các kết hợp của các kiểu Yêu cầu và Phản hồi, nhưng rõ ràng đó không phải là điều mong muốn. Vì vậy, tôi đang thiếu gì?
Đã có thể tìm ra, sử dụng RegistrationConvention để làm phong phú từng loại hình đóng của giao diện trực tiếp. Tôi đã đăng những gì tôi đã làm, nhưng tôi không thể cho một vài giờ. – Robert