Autofac - Inject ModelState into Service - asp.net-mvc-3

I want to be able to inject model state into a service.
Service
public ThirdPartyService(IValidationDictionary dict)
{
// IValidationDictionary, in this case is a ModelStateWrapper object
// I created to wrap model state
}
Registration
builder.Register(x => new ModelStateWrapper(x.Resolve<ControllerType>().ViewData.ModelState))
.As<IValidationDictionary>().InstancePerHttpRequest();
Any ideas?

This doesn't make sense as an InstancePerHttpRequest.
There can be a lot of controllers and there can be a lot of model states during a single Http request. Even if you access the current ControllerContext object through a refference in say, HttpContext.Current , the code you will produce is prone to bugs and malfunction due to design.
What I would suggest is to create an in-memory service-like repository to store all current ModelState and retrieve them by a controller-action key like (plain stupid example):
interface IHttpRequestModelStates
{
ICollection<string, ModelState> ModelStates {get; set;}
// you can retrieve Controller:Home / Index model state
// using ModelStates["HomeIndex"]
}

Related

Not tracking a single property of an entity with EF4

My MVC action method receives an entity object (Page) that the default model binder creates from form collection data. Some of the fields are wrong or null because they were not sent in the request to the server, for example I do not send "CreateDate" and the default model binder sets this property to some default value which I don't need.
Once the object is attached it of course tries to persist all the values (including invalid/not needed ones to the database). I could of course assign manually on a per property basis but was wondering if maybe I can somehow flag a property so it is not persisted when EntityState is set to modified and SaveChanges() is called..
public ActionResult SomeMethod(Page page)
{
page.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(page);
_db.ObjectStateManager.ChangeObjectState(page, System.Data.EntityState.Modified);
_db.SaveChanges();
_db.Dispose();
}
The correct way to handle this is using different class for view model, attach empty entity to the context and assign real values per property (or let AutoMapper to handle this scenario) as #Darin suggested in the comment.
If you want to go your way you must not change state of the POCO entity but you must change state of every changed property:
public ActionResult SomeMethod(Page page)
{
page.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(page);
ObjectStateEntry entry = _db.ObjectStateManager.GetObjectStateEntry(page);
entry.SetModifiedProperty("ChangedPropertyName");
// Do the same for all other changed properties
_db.SaveChanges();
_db.Dispose();
}

The difference between object validation and persistence validation in DDD?

Right now, I have a domain entity named StyleBundle. This StyleBundle takes a list of Styles:
public class StyleBundle
{
public StyleBundle(List<Style> styles)
{
this.Styles = styles;
}
public IEnumerable<Style> Styles { get; private set;}
}
So, in my original design, a StyleBundle should never be created with an empty Style list. This was a rule that the domain experts basically said was good.
I wrote this using a guard clause in the constructor:
if (styles.Count() == 0)
throw new Exception("You must have at least one Style in a StyleBundle.");
which made sure I could not create StyleBundle in an invalid state. I thought an exception made sense here b/c a StyleBundle being created without at least one Style was exceptional in the system.
Of course, change came down the road during the rest of the project, and now it should be possible for a user to create a StyleBundle without Styles, but they should not be allowed to PERSIST a StyleBundle without Styles.
So now I'm looking at my guard clause and realizing that I can't have the exception thrown from the constructor anymore.
Moving forward, I have a Service/Application layer that my code-behinds interact with when they're working with StyleBundles. In my Service Layer, I have a StyleBundleService class, and that class exposes basic functionality to the UI... among them is "CreateStyleBundle".
It seems as if I'll have to have my Service Layer check to see if the StyleBundle does or does not have any Styles before it's persisted to the database, but something about this decision feels "wrong" to me.
Anyone run into a similar thing? Basically, the different between the state of an object being valid when "new'ed up" vs. the state of the same object when it comes to persistence?
Thanks!
Mike
I would add an IsValid method to your entity. This would check if the entity is currently in a valid state (in your case, check if there are styles).
This method can be called from your Repository to check if an entity may be persisted. You can add more rules to the IsValid method for specific entities and you can implement something like a collection of Validation errors is you want to throw a meaningful exception.
Expanding what Wouter said, plus handy BeforeSaving and BeforeDeleting methods:
public interface IDomainObject<T>
{
bool IsValid();
}
public interface IEntity<T> : IDomainObject<T>
{
}
public interface IAggregateRoot<T> : IEntity<T>
{
void BeforeSaving();
void BeforeDeleting();
}
public interface IAggregateRoot { //or simply IEntity depending on the model
bool IsValid();
}
public class StyleBundle : IAggregateRoot<T> {
return styles.Count() > 0
}
public class StyleBundleRepository : Repository<StyleBundle> {
}
public abstract class Repository<T> : IRepository<T> where T : class, IAggregateRoot<T> {
public T Save(T t)
{
t.BeforeSaving(); //for all AggregateRoots, maybe logging what the aggregate was like before the changes
if(!t.IsValid())
throw Exeception("Entity invalid");
EntityStore.Current.SaveChanges();
// "AfterSaving" here, i.e.: log how the entity looks after the update
}
}
Edit: I dont personally use the IsValid idea, I go with a full class of EntityValidationErrors where I can report back to the client what was wrong before attempting to save, things that shouldnt be null, shouldnt be empty (like your Styles etc)
There are multiple strategies:
Some developers prefer to create 2 methods in the entity itself, one called IsValid() which validates the entity in terms of business rules (general validation) and another one called IsValidForPersistence() which validates the entity for persistence.
Regarding IsValid() I prefer instead not to allow invalid state in the first place by validating all inputs, and to support invariants I use factory or builder.
you may check the link http://www.codethinked.com/thoughts-on-domain-validation-part-1
for some thoughts.
I know, this question is three years old, but seeing the current answer is something I like to respond to. We are talking about the domain data. Hence, there can't be a valid StyleBundle with 0 objects. I imagine, you have a frontend editor somewhere, were you create a "new" StyleBundle and have to add at least one style, before hitting the "save" button.
At this point in the frontend, you won't have a domain object. You may have a data transfer object, that will be send with a "CreateNewStyleBundle" command.
In my opinion, the domain object must be agnostic to persitance and should always be in a valid state. If you have to call a "IsValid" method, you circumvent the whole idea of having domain objects in the first place.
That's just my humble opinion.

MVC 3 passing entity as an Interface

I'm currently working on an MVC 3 project using Ninject as my DI, the business objects are stored in a separate assembly. I'm running into an issue with the controller parameters, when posting back for CRUD operations I'm getting the error "Cannot create an instance of an interface". I am aware that you can't create an instance of an interface, but it seems like the only way I can get around this is to use a custom model binder and pass the FormCollection through. This seems really messy and I want to keep as much type specific code out of the project as I can - hence interfaces everywhere and Ninject to DI the concretes. Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
Some code to describe what I have:
public ActionResult Create()
{
// I'm thinking of using a factory pattern for this part
var objectToCreate = new ConcereteType();
return (objectToEdit);
}
[HttpPost]
public ActionResult Create(IRecord record)
{
// check model and pass to repository
if (ModelState.IsValue)
{
_repository.Create(record);
return View();
}
return View(record);
}
Has anyone run into this before? How did you get over it?
Thanks!
but it seems like the only way I can get around this is to use a custom model binder
A custom model binder is the correct way to go. And by the way you should use view models as action arguments, not domain models or interfaces.
Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
I don't know why you think that a custom model binder would make things messy. For me it's a great way to separate mapping logic into a reusable class. And, no you will not lose DataAnnotations. They will work perfectly fine on the concrete instance that the custom model binder would return.
Data passed to controllers action are simply holders for values. There shouldn't be any logic in them so there is nothing to decouple from. You can use concrete types (e.g Record) instead of interface (IRecord)
I made the same simple mistake. Ninject injects parameters into your constructor, but you added parameters to the Index Controller action.
It should look like this:
public class HomeController : Controller
{
private IRecord _record;
public HomeController(IRecord record)
{
_record = record;
}
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " +
_record .HelloWorld();
return View();
}
}
Make sense?

What, exactly, does a modelbinder do? How to use it effectively?

I was researching something and came across this blog post at buildstarted.com about model binders. It actually works pretty darn well for my purposes but I am not sure exactly whats going on behind the scenes. What I did was create a custom ModelBinder called USerModelBinder:
public class UserModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
MyEntities db = new MyEntities();
User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
return user;
}
}
Then in my Global.asax.cs I have:
ModelBinders.Binders.Add(typeof(User), new UserModelBinder());
My understanding is that using the model binder allows me to NOT have to use the following lines in every controller action that involves a "User". So instead of passing in an "id" to the action, the modelbinder intercepts the id, fetches the correct "item"(User in my case) and forwards it to the action for processing.
MyEntities db = new MyEntities();
User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
I also tried using an annotation on my User class instead of using the line in Global.asax.cs:
[ModelBinder(typeof(UserModelBinder))]
public partial class User
{
}
I'm not looking for a 30 page white paper but I have no idea how the model binder does what it does. I just want to understand what happens from when a request is made to the time it is served. All this stuff "just working" is not acceptable to me, lol. Also, is there any difference between using the annotation versus adding it in Global.asax.cs? They seem to work the same in my testing but are there any gotchas?
Usually the Model Binder (in MVC) looks at you Action method and sees what it requires (as in, the objects types). It then tries to find the values from the HTTP Request (values in the HTTP Form, QueryString, Json and maybe other places such as cookies etc. using ValueProviders). It then creates a new object with the parameters that it retrieves.
IMO What you've done is not really "model binding". In the sense that you've just read the id and fetched the object from the DB.
example of usual model binding:
// class
public class SomeClass
{
public int PropA {get;set;}
public string PropB {get;set;}
}
// action
public ActionResult AddSomeClass(SomeClass classToBind)
{
// implementation
}
// pseudo html
<form action="">
<input name="PropA" type="text" />
<input name="PropB" type="text" />
</form>
if you post a form that contains the correct values (lets say you post a form with PropA and PropB ) the model binder can identify that you've sent those values in the form and build a SomeClass object.
If you really want to create a real working example you should use a strongly typed View and use HtmlHelper's EditorFor (or EditorForModel) to create all the correct names that MVC needs.
--
for reference MVC's default binder is the DefaultModelBinder, and some (there are more, you can look around in the System.Web.Mvc namespace) ValueProviders that it uses by default are the FormValueProvider and the QueryStringValueProvider
So, as I already said, how this basically works is that the default model binder reads the model that the action is recieving (say SomeClass in the example) reads what are the values that it can read (say PropA and PropB) and asks the ValueProviders for the correct values for the properties.
Also, if I recall correctly, you can also see the value providers in runtime using the ValueProviderFactories static class.
A ModelBinder looks at the arguments of the selected Controller action's method signature, then converts the values from the ValueProviders into those arguments.
This happens when the ControllerActionInvoker invokes the action associated with the ControllerContext, because the Controller's Execute() method told it to.
For more about the ASP.NET MVC execution process, see Understanding the MVC Application Execution Process

Where to put restrictions on entities when separating Business layer from Data Layer

I am attempting to create the the business and data layers for my big ASP.NET MVC application. As this is the first time for me attempting a project of this scale I am reading some books and trying to take good care at separating things out properly. Usually my applications mix the business logic and data access layers, and multiple business entities are intertwined in the single class (which has confused me a few times when I was trying to figure out where to add things).
Most of what I have been reading is to separate out the business and data layers. This seems all fine and dandy, but I am having trouble visualizing exactly how to do this in some scenarios. For example, let's say I am creating a system that allows admins to add a new product to the system:
public class Product
{
public int Id { get; private set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Then I separate out the data access by creating a repository
public class ProductRepository
{
public bool Add(Product product);
}
Let's say I want to require a product's name to have at least 4 characters. I can't see how to do this cleanly.
One idea I had was to expand the Name's set property and only set it if it's 4 characters long. However, there is no way for a method that is creating the product to know the name didn't get set except that Product.Name != whatever they passed in.
Another idea I had is to put it in the Add() method in the repository, but then I have my business logic right there with the data logic, which also means if the Add call fails I don't know if it failed for the business logic or because the DAL failed (and it also means I can't test it using mock frameworks).
The only thing I can think of is to put my DAL stuff in a 3rd layer that gets called from the Add() method in the repository, but I don't see this in any of the domain modelling examples in my book or on the web (that I've seen at least). It also adds to the complexity of the domain models when I am not sure it is needed.
Another example is wanting to make sure that a Name is only used by one product. Would this go in the Product class, ProductRepository Add() method, or where?
As a side note, I plan to use NHibernate as my ORM however, to accomplish what I want it (theoretically) shouldn't matter what ORM I am using since TDD should be able to isolate it all.
Thanks in advance!
I usually approach this by using a layered architecture. How to do this? You basically have the following (ideally) VS projects:
Presentation layer (where the UI stuff resides)
Business layer (where the actual business logic resides)
Data access layer (where you communicate with your underlying DBMS)
For decoupling all of them I use so-called interface layers s.t. in the end I have
Presentation layer (where the UI
stuff resides)
IBusiness layer (containing the interfaces for the
business layer)
Business layer (where
the actual business logic resides)
IDataAccess layer (containing the
interfaces for the DAO layer)
Data access layer (where you communicate
with your underlying DBMS)
This is extremely handy and creates a nicely decoupled architecture. Basically your presentation layer just accesses the interfaces and not the implementations itself. For creating the according instances you should use a Factory or preferably some dependency injection library (Unity is good for .Net apps or alternatively Spring.Net).
How does this impact on your business logic / testability of your app?
It is probably too long to write everything in detail, but if you're concerned about having a well testable design you should absolutely consider dependency injection libraries.
Using NHibernate,...whatever ORM
Having a DAO layer completely separated through the interfaces from the other layers you can use whatever technology behind for accessing your underlying DB. You could directly issue SQL queries or use NHibernate, as you wish. The nice thing is that it is totally independent from the rest of your app. You could event start today by writing SQLs manually and tomorrow exchange your DAO dll with one that uses NHibernate without a single change in your BL or presentation layer.
Moreover testing your BL logic is simple. You may have a class like:
public class ProductsBl : IProductsBL
{
//this gets injected by some framework
public IProductsDao ProductsDao { get; set; }
public void SaveProduct(Product product)
{
//do validation against the product object and react appropriately
...
//persist it down if valid
ProductsDao.PersistProduct(product);
}
...
}
Now you can easily test the validation logic in your SaveProduct(...) method by mocking out the ProductDao in your test case.
Put things like the product name restriction in the domain object, Product, unless you want to allow products with fewer than 4 characters in some scenarios (in this case, you'd apply the 4-character rule at the level of the controller and/or client-side). Remember, your domain objects may be reused by other controllers, actions, internal methods, or even other applications if you share the library. Your validation should be appropriate to the abstraction you are modeling, regardless of application or use case.
Since you are using ASP .NET MVC, you should take advantage of the rich and highly extensible validation APIs included in the framework (search with keywords IDataErrorInfo MVC Validation Application Block DataAnnotations for more). There are lots of ways for the calling method to know that your domain object rejected an argument -- for example, throwing the ArgumentOutOfRangeException.
For the example of ensuring that product names are unique, you would absolutely not put that in Product class, because this requires knowledge of all other Products. This logically belongs at the persistence layer and optionally, the repository. Depending on your use case may warrant a separate service method that verifies that the name does not already exist, but you shouldn't assume that it will still be unique when you later try to persist it (it has to be checked again, because if you validate uniqueness and then keep it around a while longer before persisting, someone else could still persist a record with the same name).
This is the way I do it:
I keep the validation code in the entity class, which inherits some general Item Interface.
Interface Item {
bool Validate();
}
Then, in the repository's CRUD functions i call the appropriate Validate function.
This way all the logic paths are validating my values, but i need to look only in one place to see what that validation really is.
Plus, sometimes you use the entities outside the repository scope, for example in a View. So if the validation is separated, each action path can test for validation without asking the repository.
For restrictions I utilize the partial classes on the DAL and implement the data annotation validators. Quite often, that involves creating custom validators but that works great as it's completely flexible. I've been able to create very complex dependent validations that even hit the database as part of their validity checks.
http://www.asp.net/(S(ywiyuluxr3qb2dfva1z5lgeg))/learn/mvc/tutorial-39-cs.aspx
In keeping with the SRP (single responsibility principle), you might be better served if the validation is separate from the product's domain logic. Since it's required for data integrity, it should probably be closer to the repository - you just want to be sure that validation is always run without having to give it thought.
In this case you might have a generic interface (e.g. IValidationProvider<T>) that is wired to a concrete implementation through an IoC container or whatever your preference may be.
public abstract Repository<T> {
IValidationProvider<T> _validationProvider;
public ValidationResult Validate( T entity ) {
return _validationProvider.Validate( entity );
}
}
This way you can test your validation separately.
Your repository might look like this:
public ProductRepository : Repository<Product> {
// ...
public RepositoryActionResult Add( Product p ) {
var result = RepositoryResult.Success;
if( Validate( p ) == ValidationResult.Success ) {
// Do add..
return RepositoryActionResult.Success;
}
return RepositoryActionResult.Failure;
}
}
You could go a step further, if you intend on exposing this functionality via an external API, and add a service layer to mediate between the domain objects and the data access. In this case, you move the validation to the service layer and delegate data access to the repository. You may have, IProductService.Add( p ). But this can become a pain to maintain due to all of the thin layers.
My $0.02.
Another way to accomplish this with loose coupling would be to create validator classes for your entity types, and register them in your IoC, like so:
public interface ValidatorFor<EntityType>
{
IEnumerable<IDataErrorInfo> errors { get; }
bool IsValid(EntityType entity);
}
public class ProductValidator : ValidatorFor<Product>
{
List<IDataErrorInfo> _errors;
public IEnumerable<IDataErrorInfo> errors
{
get
{
foreach(IDataErrorInfo error in _errors)
yield return error;
}
}
void AddError(IDataErrorInfo error)
{
_errors.Add(error);
}
public ProductValidator()
{
_errors = new List<IDataErrorInfo>();
}
public bool IsValid(Product entity)
{
// validate that the name is at least 4 characters;
// if so, return true;
// if not, add the error with AddError() and return false
}
}
Now when it comes time to validate, ask your IoC for a ValidatorFor<Product> and call IsValid().
What happens when you need to change the validation logic, though? Well, you can create a new implementation of ValidatorFor<Product>, and register that in your IoC instead of the old one. If you are adding another criterion, however, you can use a decorator:
public class ProductNameMaxLengthValidatorDecorator : ValidatorFor<Person>
{
List<IDataErrorInfo> _errors;
public IEnumerable<IDataErrorInfo> errors
{
get
{
foreach(IDataErrorInfo error in _errors)
yield return error;
}
}
void AddError(IDataErrorInfo error)
{
if(!_errors.Contains(error)) _errors.Add(error);
}
ValidatorFor<Person> _inner;
public ProductNameMaxLengthValidatorDecorator(ValidatorFor<Person> validator)
{
_errors = new List<IDataErrorInfo>();
_inner = validator;
}
bool ExceedsMaxLength()
{
// validate that the name doesn't exceed the max length;
// if it does, return false
}
public bool IsValid(Product entity)
{
var inner_is_valid = _inner.IsValid();
var inner_errors = _inner.errors;
if(inner_errors.Count() > 0)
{
foreach(var error in inner_errors) AddError(error);
}
bool this_is_valid = ExceedsMaxLength();
if(!this_is_valid)
{
// add the appropriate error using AddError()
}
return inner_is_valid && this_is_valid;
}
}
Update your IoC configuration and you now have a minimum and maximum length validation without opening up any classes for modification. You can chain an arbitrary number of decorators in this way.
Alternatively, you can create many ValidatorFor<Product> implementations for the various properties, and then ask the IoC for all such implementations and run them in a loop.
Alright, here is my third answer, because there are so very many ways to skin this cat:
public class Product
{
... // normal Product stuff
IList<Action<string, Predicate<StaffInfoViewModel>>> _validations;
IList<string> _errors; // make sure to initialize
IEnumerable<string> Errors { get; }
public void AddValidation(Predicate<Product> test, string message)
{
_validations.Add(
(message,test) => { if(!test(this)) _errors.Add(message); };
}
public bool IsValid()
{
foreach(var validation in _validations)
{
validation();
}
return _errors.Count() == 0;
}
}
With this implementation, you are able to add an arbitrary number of validators to the object without hardcoding the logic into the domain entity. You really need to be using IoC or at least a basic factory for this to make sense, though.
Usage is like:
var product = new Product();
product.AddValidation(p => p.Name.Length >= 4 && p.Name.Length <=20, "Name must be between 4 and 20 characters.");
product.AddValidation(p => !p.Name.Contains("widget"), "Name must not include the word 'widget'.");
product.AddValidation(p => p.Price < 0, "Price must be nonnegative.");
product.AddValidation(p => p.Price > 1, "This is a dollar store, for crying out loud!");
U can use a other validation system. you can add a method to IService in service layer such as:
IEnumerable<IIssue> Validate(T entity)
{
if(entity.Id == null)
yield return new Issue("error message");
}

Resources