Я бы на самом деле подошел к этому немного по-другому, отдавая предпочтение композиции вместо наследования . Это означает, что я бы инкапсулировал детали манипулирования свойством и передавал различные реализации в один связыватель модели.
Сначала определите интерфейс, который представляет привязку одного свойства:
public interface IPropertyBinder
{
void SetPropertyValue(object model, ModelBindingContext context);
}
Затем реализуйте его, используя параметры, изначально взятые из EncodedPropertyModelBinder
:
public sealed class PropertyBinder : IPropertyBinder
{
private readonly IEncodingService _encodingService;
private readonly string _propertyName;
public PropertyBinder(IEncodingService encodingService, string propertyName)
{
_encodingService = encodingService;
_propertyName = propertyName;
}
public void SetPropertyValue(object model, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(_propertyName);
if(value != null && !value.AttemptedValue.IsNullOrEmpty())
{
var encodedValue = _encodingService.Encode(value.AttemptedValue);
var property = model.GetType().GetProperty(_propertyName);
property.SetValue(model, encodedValue, null);
}
}
}
Затем внедрите EncodedPropertyModelBinder
, используя новый интерфейс:
public class EncodedPropertyModelBinder : DefaultModelBinder
{
private readonly IPropertyBinder _propertyBinder;
public EncodedPropertyModelBinder(IPropertyBinder propertyBinder)
{
_propertyBinder = propertyBinder;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = base.BindModel(controllerContext, bindingContext);
if(model != null)
{
_propertyBinder.SetPropertyValue(model, bindingContext);
}
return model;
}
}
Наконец, зарегистрируйте две версии модели представления, используя именованные экземпляры Autofac, передавая в различных конфигурациях PropertyBinder
:
builder.
Register(c => new EncodedPropertyModelBinder(new PropertyBinder(c.Resolve<IEncodingService>(), "Answer")))
.Named<EncodedPropertyModelBinder>("AnswerBinder");
builder.
Register(c => new EncodedPropertyModelBinder(new PropertyBinder(c.Resolve<IEncodingService>(), "SecretKey")))
.Named<EncodedPropertyModelBinder>("SecretKeyBinder");