Я пытаюсь реализовать обработку исключений для своего веб-приложения MVC с помощью nice example, предоставленного Steven, в качестве ответа на вопрос StackOverFlow.Autofac - Тип возвращаемого бетона для абстрактного общего типа
Внизу конфигурация, необходимая для Ninject, предусмотрена так, что контроллер может работать и работать. Я использую Autofac в качестве контейнера IoC. Любая помощь в определении контроллера для создания экземпляра класса обслуживания была бы высоко оценена. Кроме того, мне было бы интересно увидеть пример того, как класс службы может быть вызван с контроллера, если мы не используем какой-либо контейнер IoC.
UPDATE: Следуя примеру Стивена, эти классы, которые я мог бы написать до сих пор:
Бизнес-Сервис-слойный:
namespace BusinessService.ValidationProviders
{
public interface IValidationProvider
{
void Validate(object entity);
void ValidateAll(IEnumerable entities);
}
}
namespace BusinessService.ValidationProviders
{
public interface IValidator
{
IEnumerable<ValidationResult> Validate(object entity);
}
}
namespace BusinessService.ValidationProviders
{
public class ValidationResult
{
public ValidationResult(string key, string message)
{
this.Key = key;
this.Message = message;
}
public string Key { get; private set; }
public string Message { get; private set; }
}
}
namespace BusinessService.ValidationProviders
{
public abstract class Validator<T> : IValidator
{
IEnumerable<ValidationResult> IValidator.Validate(object entity)
{
if (entity == null) throw new ArgumentNullException("entity");
return this.Validate((T)entity);
}
protected abstract IEnumerable<ValidationResult> Validate(T entity);
}
}
namespace BusinessService.ValidationProviders
{
public class ValidationProvider : IValidationProvider
{
private readonly Func<Type, IValidator> _validatorFactory;
public ValidationProvider(Func<Type, IValidator> validatorFactory)
{
this._validatorFactory = validatorFactory;
}
public void Validate(object entity)
{
var results = this._validatorFactory(entity.GetType())
.Validate(entity).ToArray();
if (results.Length > 0) throw new ValidationException(results);
}
public void ValidateAll(IEnumerable entities)
{
var results = (
from entity in entities.Cast<object>()
let validator = this._validatorFactory(entity.GetType())
from result in validator.Validate(entity)
select result).ToArray();
if (results.Length > 0) throw new ValidationException(results);
}
}
}
namespace BusinessService.ValidationProviders
{
public sealed class NullValidator<T> : Validator<T>
{
protected override IEnumerable<ValidationResult> Validate(T entity)
{
return Enumerable.Empty<ValidationResult>();
}
}
}
namespace BusinessService.ValidationProviders
{
public class ValidationException : Exception
{
public ValidationException(IEnumerable<ValidationResult> r)
: base(GetFirstErrorMessage(r))
{
this.Errors =
new ReadOnlyCollection<ValidationResult>(r.ToArray());
}
public ReadOnlyCollection<ValidationResult> Errors { get; private set; }
private static string GetFirstErrorMessage(
IEnumerable<ValidationResult> errors)
{
return errors.First().Message;
}
}
}
namespace BusinessService.ValidationProviders
{
public class NotificationValidator: Validator<NotificationViewModel>
{
protected override IEnumerable<ValidationResult> Validate(NotificationViewModel entity)
{
if (entity.PolicyNumber.Length == 0)
yield return new ValidationResult("PolicyNumber",
"PolicyNumber is required.");
if (entity.ReceivedBy.Length == 0)
yield return new ValidationResult("ReceivedBy",
"ReceivedBy is required.");
if (entity.ReceivedDate < DateTime.Now)
yield return new ValidationResult("ReceivedDate",
"ReceivedDate cannot be earlier than the current date.");
}
}
}
namespace BusinessService
{
public class NotificationService : INotificationService
{
private readonly IValidationProvider _validationProvider;
public NotificationService(IValidationProvider validationProvider)
{
this._validationProvider = validationProvider;
}
public void CreateNotification(NotificationViewModel viewModel)
{
// Do validation here...
this._validationProvider.Validate(viewModel);
// Persist the record to the repository.
}
}
}
ViewModels слой:
namespace ViewModels
{
public class NotificationViewModel
{
public int ID { get; set; }
public string PolicyNumber { get; set; }
public string ReceivedBy { get; set; }
public DateTime ReceivedDate { get; set; }
}
}
UI-слой:
namespace ExceptionHandling.Controllers
{
public class NotificationController : Controller
{
private INotificationService _service;
private IValidationProvider _validationProvider;
public NotificationController()
{
_validationProvider = null; // Need to instantiate this!
this._service = new NotificationService(_validationProvider);
}
public NotificationController(INotificationService service)
{
// Need to instantiate service here..
}
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(NotificationViewModel viewModel)
{
if (ModelState.IsValid)
{
this._service.CreateNotification(viewModel);
return RedirectToAction("Index", "Home");
}
return View();
}
}
}
Ищете некоторую помощь для создания экземпляра класса NotificationService с контроллера. Мы используем Autofac для IoC. Было бы здорово, если бы кто-то мог указать мне в правильном направлении, как настроить его для Autofac. Спасибо заранее!
+1 для того, чтобы понравиться моему ответу :-), но ... Думаю, вы должны уточнить свой вопрос, чтобы быть более конкретным, вместо того, чтобы указывать на какой-то код где-то глубоко в каком-то ответе stackoverflow. Вы должны сделать это как можно проще для тех, кто читает ваш вопрос, чтобы понять, что вы хотите знать, без необходимости следить за любыми ссылками, которые вы предоставляете. – Steven
@Steven Я скопировал код в соответствии с вашим предложением (первоначально был неохотно, так как он был таким же, как и пример, который вы предоставили на другом ответе SO!) – beastieboy
Честно говоря, мой ответ - не лучшее решение. Если можно, не используйте абстракции IXxxService, а используйте [обработчики команд] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91). Таким образом вы можете украсить либо обработчики, либо репозитории напрямую с помощью декоратора, который добавляет проверку. – Steven