我正在尝试使用nice example提供的Steven为我的MVC Web应用程序实现异常处理,作为StackOverFlow问题的答案。
在底部,提供了Ninject所需的配置,以便控制器可以启动并运行。我正在使用Autofac作为IoC容器。任何有关定义控制器以实例化服务类的帮助都将受到高度赞赏。另外,如果我们不使用任何IoC容器,我会有兴趣看到如何从控制器调用服务类的示例。
更新: 继Steven的例子之后,这些是我到目前为止可以编写的类:
商业服务 - 层:
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类。我们在IoC中使用Autofac。如果有人可以指出我如何为Autofac配置它,那将会很棒。非常感谢提前!
答案 0 :(得分:0)
在努力寻找将Steven的解决方案与Autofac集成的方法之后,我遇到了Patrick Desjardin的博客文章:
The three layers of validation(控制器,服务和存储库)。
我发现这很容易,因为您不必注入任何验证提供程序。此外,它很容易与任何层集成。请确保您也阅读了后续帖子:
How to validate model object with Asp.Net MVC correctly
Model validation and Entity Framework 4.3
任何比较两种解决方案的意见都将非常感激。非常感谢!