2013-08-16 5 views
1

Я пытаюсь реализовать обработку исключений для своего веб-приложения 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. Спасибо заранее!

+0

+1 для того, чтобы понравиться моему ответу :-), но ... Думаю, вы должны уточнить свой вопрос, чтобы быть более конкретным, вместо того, чтобы указывать на какой-то код где-то глубоко в каком-то ответе stackoverflow. Вы должны сделать это как можно проще для тех, кто читает ваш вопрос, чтобы понять, что вы хотите знать, без необходимости следить за любыми ссылками, которые вы предоставляете. – Steven

+0

@Steven Я скопировал код в соответствии с вашим предложением (первоначально был неохотно, так как он был таким же, как и пример, который вы предоставили на другом ответе SO!) – beastieboy

+0

Честно говоря, мой ответ - не лучшее решение. Если можно, не используйте абстракции IXxxService, а используйте [обработчики команд] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91). Таким образом вы можете украсить либо обработчики, либо репозитории напрямую с помощью декоратора, который добавляет проверку. – Steven

ответ

0

После пытаются найти способ интеграции решения Стивена с Autofac, я наткнулся на блоге Patrick Десжардин в:

The three layers of validation (контроллер, служба & Repository).

Мне было легко, поскольку вам не нужно вводить никаких поставщиков валидации. Кроме того, его легко интегрировать с любым слоем. Пожалуйста, убедитесь, что вы читали последующие посты, а также:

How to validate model object with Asp.Net MVC correctly

Model validation and Entity Framework 4.3

Любые мнения, что сравнивает оба решения были бы оценены. Большое спасибо!

Смежные вопросы