Omu.ValueInjecter在允许集合发生之前检查属性

时间:2014-01-30 13:44:32

标签: c# asp.net-mvc valueinjecter

我需要扩展Omu.ValueInjecter以在进行属性赋值之前执行检查。给定下面的代码示例,只有在SetA为true时才会分配prop A.我怀疑LoopValueInjection在这里不是正确的基类,但有人可以更正下面的代码,以便我可以在注入过程中检查SetA吗?

var source = new Source() { A = 3 };
var dest = new Dest();
dest.InjectFrom<MyInjector>(source);

public class Source
{
    public int A { get; set; }
    public bool SetA { get; set; }
}
public class Dest
{
    public int A { get; set; }
}

public class MyInjector : LoopValueInjection // or some other base class!
{
    protected override bool AllowSetValue(object value)
    {
        // check SetA!!
        //return base.AllowSetValue(value);
    }
}

3 个答案:

答案 0 :(得分:2)

好的,我现在就开始工作了。下面是正确的代码。我错过了完全符合我目的的UseSourceProp重载。

我试图解决的问题是在将视图模型发布到操作后使用MVC,您必须将视图模型数据复制到数据模型中。初始化数据模型时,可能会设置某些默认值。注入视图模型时,这些默认值将被覆盖。如果已经设置了视图模型属性,则覆盖它们是正确的,但是我的默认值被未通过后期操作设置的视图模型值覆盖。

解决方案是在视图模型中放置一个标志,指示是否已设置属性。每个属性的setter我只是更新了基类中的公共列表字符串对象。

在UseSourceProp方法的下面的代码中,您可以看到如果SetProperties中不存在正在处理的属性名称,则该方法返回false并且未设置该属性。

var source = new Source() { A = 3 };
var dest = new Dest();
dest.InjectFrom<MyInjector>(source);

public class Source
{
    public int A { get; set; }
    public bool SetA { get; set; }
}
public class Dest
{
    public int A { get; set; }
}

public class MyInjector : LoopValueInjection // or some other base class!
{
    protected override void Inject(object source, object target)
    {
        if (source is BaseEntityViewModel) _baseEntityViewModel = (BaseEntityViewModel)source;
        base.Inject(source, target);
    }
    protected override bool UseSourceProp(string sourcePropName)
    {
        if (_baseEntityViewModel is BaseEntityViewModel)
            return _baseEntityViewModel.SetProperties.Contains(sourcePropName);
        else
            return base.UseSourceProp(sourcePropName);
    }
}

答案 1 :(得分:1)

我认为覆盖SetValue方法可能就是您所需要的。这是对此处文档的略微修改:http://valueinjecter.codeplex.com/wikipage?title=Getting%20started&referringTitle=Documentationhttp://valueinjecter.codeplex.com/discussions/355101

public class MyInjector : LoopValueInjection
{       
    //by default is return sourcePropertyValue; override to change behaviour 
    protected override object SetValue(ConventionInfo c)
    {
        // this is just a sample, but you could write anything here
        return new Dest 
        { 
            //Check if source value is true and only then set property

            if(c.SourceProp.Name == "SetA")
            {
              var setASourceVal = c.TargetProp.Value As bool;
              if(setASourceVal)
              {
                A = sourcePropertyValue;
              }
            }
        }
    }
}

答案 2 :(得分:0)

取决于您使用哪种注射剂, 使用ConventionInjection,您可以使用Match方法中的值 https://valueinjecter.codeplex.com/wikipage?title=step%20by%20step%20explanation&referringTitle=Home

对于LoopValueInjection,您可以覆盖AllowSetValue

最新(最快)的注射是:https://valueinjecter.codeplex.com/wikipage?title=SmartConventionInjection&referringTitle=Home

  

与ConventionInjection相比,它有一个限制,您没有匹配方法中的源和目标属性的值,但是您在SetValue方法中有它们,并且您可以取消对该属性的值的设置,如果你将false设置为ref参数setValue