So, I've been messing around with validation in .NET, trying to find a good solid way of implementing validation in a business layer (such as discussed in this MSDN article).
The idea is that I pass a controller's ModelState to the business service, and then the service performs validation and updates the ModelState.
However, one thing I've noticed is that ModelStateDictionary exists in two different namespaces:
While I could just "pick one", I don't want my business layer to have any dependencies on the presentation layer. For instance, if I picked MVC the business service classes would need to expect the MVC-namespaced version of ModelStateDictionary...meaning they would be dependent on an MVC presentation layer.
So, I was wondering if anybody had suggestions on how to approach this?
My attempt was to create an adapter/Inteface IModelStateDictionary, and I got close... But, the Modelstate uses a ValueProviderResult class (also System.Web.MVC) that has a virtual method ConvertTo(). I'm not sure how I can get around this...might be a simple pattern I haven't learned, yet, but at my level of experience am not sure if it's really a show stopper...
...or that I could approach this in a better way?
Advice would be Most Appreciated!
Thanks,
Chris
Edit: Code below
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common.Interfaces
{
public interface IModelStateDictionary
{
IModelState this[string key] { get; set; }
int Count { get; }
bool IsReadOnly { get; }
bool IsValid { get; }
ICollection<string> Keys { get; }
ICollection<IModelState> Values { get; }
void Add(KeyValuePair<string, IModelState> item);
void Add(string key, IModelState value);
void AddModelError(string key, string errorMessage);
void AddModelError(string key, Exception exception);
bool Contains(KeyValuePair<string, IModelState> item);
bool ContainsKey(string key);
void CopyTo(KeyValuePair<string, IModelState>[] array, int arrayIndex);
IEnumerator<KeyValuePair<string, IModelState>> GetEnumerator();
bool IsValidField(string key);
void Merge(IModelStateDictionary dictionary);
bool Remove(string key);
bool Remove(KeyValuePair<string, IModelState> item);
void SetModelValue(string key, IValueProviderResult value);
bool TryGetValue(string key, out IModelState value);
}
public interface IModelState
{
IModelErrorCollection Errors { get; }
IValueProviderResult Value { get; set; }
}
public interface IValueProviderResult
{
string AttemptedValue { get; protected set; }
CultureInfo Culture { get; protected set; }
object RawValue { get; protected set; }
object ConvertTo(Type type);
virtual object ConvertTo(Type type, CultureInfo culture);
}
public interface IModelErrorCollection
{
void Add(string errorMessage);
void Add(Exception exception);
}
}