ValueInjecter 将 ViewModel 映射到域

发布于 2024-12-22 07:21:27 字数 2649 浏览 1 评论 0原文

我正在使用 valueinjecter,想知道当视图模型具有视图模型集合时,如何对域进行视图模型?

假设我现在有了这个域名,

   public class MyDomain
   {
       public IList<MyOtherDomain> MyOtherDomains {get; set;}
   }

   public class MyOtherDomain
   {
       public string Name {get; set;}
   }

   public class MyMasterVM
   {
       public IList<MyOtherVm> MyOtherDomains {get; set;}
   }    

   public class MyOtherVm
   {
       public string Name {get; set;}
   }

我该如何进行注入?我需要使用 valueinjector 手动映射这些吗?

public ActionResult Method(MyMasterVM vm)
{
   MyDomain d = new MyDomain();
    d.InjectFrom<UnflatLoopValueInjection>(vm);
}

编辑

经过一番尝试后,我让模拟器开始工作了。然而,我的与测试中的不同,

// sample test
   public class FooBar : TypeMapper<Foo, Bar>
        {
            public override Bar Map(Foo source, Bar target)
            {
                base.Map(source, target);
                target.NoConvention = source.Name + source.Xyz + source.Props;
                return target;
            }
        }

             [Test]
    public void MapShouldMapCollectionPropertiesAndUseFooBarTypeMapper()
    {
        MapperFactory.AddMapper(new FooBar());
        var foo = new Foo
        {
            Foos = new List<Foo>
                       {
                           new Foo{Name = "f1",Props = "v",Xyz = 19},
                           new Foo{Name = "f2",Props = "i",Xyz = 7},
                           new Foo{Name = "f3",Props = "v",Xyz = 3},
                       }
        };

        var bar = Mapper.Map<Foo, Bar>(foo);

        Assert.AreEqual(foo.Foos.Count(), bar.Foos.Count());

        var ffoos = foo.Foos.ToArray();
        var bfoos = bar.Foos.ToArray();

        for (var i = 0; i < ffoos.Count(); i++)
        {
            Assert.AreEqual(ffoos[i].Name, bfoos[i].Name);
            Assert.AreEqual(ffoos[i].Name + ffoos[i].Xyz + ffoos[i].Props, bfoos[i].NoConvention);
        }
    }

        // mine
public class Test : TypeMapper<IList<MyOtherVm>, IList<MyOtherDomain>> 
    {
        public override IList<MyOtherDomain> Map(IList<MyOtherVm> source, IList<MyOtherDomain> target)
        {
            // not sure if I always have to call base
            // mapping would happen here.
            return base.Map(source, target);
        }
    }

       MapperFactory.AddMapper(new Test());
            IList<MyOtherDomain> otherDomains= new List<MyOtherDomain>();
           MapperVj.Map(vm.MyOtherDomains , otherDomains);

我必须指定它是一个 IList,否则它似乎永远不会进入我的重写方法。

I am playing around with valueinjecter and wondering how do I do viewmodels to domains when the view model has a collection of viewmodels?

Say I have this domain

   public class MyDomain
   {
       public IList<MyOtherDomain> MyOtherDomains {get; set;}
   }

   public class MyOtherDomain
   {
       public string Name {get; set;}
   }

   public class MyMasterVM
   {
       public IList<MyOtherVm> MyOtherDomains {get; set;}
   }    

   public class MyOtherVm
   {
       public string Name {get; set;}
   }

now how do I do my injecting? Do I need to manually map these with valueinjector?

public ActionResult Method(MyMasterVM vm)
{
   MyDomain d = new MyDomain();
    d.InjectFrom<UnflatLoopValueInjection>(vm);
}

Edit

After some playing around I got the simulator to work. However mine is different than the one in the tests

// sample test
   public class FooBar : TypeMapper<Foo, Bar>
        {
            public override Bar Map(Foo source, Bar target)
            {
                base.Map(source, target);
                target.NoConvention = source.Name + source.Xyz + source.Props;
                return target;
            }
        }

             [Test]
    public void MapShouldMapCollectionPropertiesAndUseFooBarTypeMapper()
    {
        MapperFactory.AddMapper(new FooBar());
        var foo = new Foo
        {
            Foos = new List<Foo>
                       {
                           new Foo{Name = "f1",Props = "v",Xyz = 19},
                           new Foo{Name = "f2",Props = "i",Xyz = 7},
                           new Foo{Name = "f3",Props = "v",Xyz = 3},
                       }
        };

        var bar = Mapper.Map<Foo, Bar>(foo);

        Assert.AreEqual(foo.Foos.Count(), bar.Foos.Count());

        var ffoos = foo.Foos.ToArray();
        var bfoos = bar.Foos.ToArray();

        for (var i = 0; i < ffoos.Count(); i++)
        {
            Assert.AreEqual(ffoos[i].Name, bfoos[i].Name);
            Assert.AreEqual(ffoos[i].Name + ffoos[i].Xyz + ffoos[i].Props, bfoos[i].NoConvention);
        }
    }

        // mine
public class Test : TypeMapper<IList<MyOtherVm>, IList<MyOtherDomain>> 
    {
        public override IList<MyOtherDomain> Map(IList<MyOtherVm> source, IList<MyOtherDomain> target)
        {
            // not sure if I always have to call base
            // mapping would happen here.
            return base.Map(source, target);
        }
    }

       MapperFactory.AddMapper(new Test());
            IList<MyOtherDomain> otherDomains= new List<MyOtherDomain>();
           MapperVj.Map(vm.MyOtherDomains , otherDomains);

I have to specify it is a IList otherwise it never seems to go into my overridden method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红焚 2024-12-29 07:21:27

我认为您需要实现自己的自定义 IValueInjection 注入器。我的这个答案也是基于您的 MyDomain 类中的一个拼写错误。

拼写错误的假设:

MyDomain.MyOtherDomains : IList<MyOtherDomains>

而不是

MyDomain.MyOtherDomains : IList<MyOtherVm>

所以,客户注入类可能看起来像这样(如果有更好的方法,则不是 100%)

public class CustomInjecter : IValueInjection
{
    public object Map(object source, object target)
    {
        MyDomain result = new MyDomain();
        result.MyOtherDomains = new List<MyOtherDomain>();

        foreach (MyOtherVm vm in (source as MyMasterVM).MyOtherVMs)
        {
            MyOtherDomain od = new MyOtherDomain();
            // inject commonly named properties of each "child" VM
            od.InjectFrom(vm);
            result.MyOtherDomains.Add(od);
        }

        return result;
    }
}

在您的控制器中,您几乎可以像上面指定的那样使用它(只需更改注入器类型)

public ActionResult Method(MyMasterVM vm)
{
    MyDomain d = new MyDomain();
    d.InjectFrom<CustomInjecter>(vm);
    // ...
}

I think you'd need to implement your own custom IValueInjection injector. I am also basing this answer on a typo in your MyDomain class.

Assumption of typo:

MyDomain.MyOtherDomains : IList<MyOtherDomains>

and not

MyDomain.MyOtherDomains : IList<MyOtherVm>

So, the customer injection class could look like this (not 100% if there's a better way to do it)

public class CustomInjecter : IValueInjection
{
    public object Map(object source, object target)
    {
        MyDomain result = new MyDomain();
        result.MyOtherDomains = new List<MyOtherDomain>();

        foreach (MyOtherVm vm in (source as MyMasterVM).MyOtherVMs)
        {
            MyOtherDomain od = new MyOtherDomain();
            // inject commonly named properties of each "child" VM
            od.InjectFrom(vm);
            result.MyOtherDomains.Add(od);
        }

        return result;
    }
}

In your controller, you can use it almost like you specified above (just change the injector type)

public ActionResult Method(MyMasterVM vm)
{
    MyDomain d = new MyDomain();
    d.InjectFrom<CustomInjecter>(vm);
    // ...
}
独闯女儿国 2024-12-29 07:21:27

一种快速简单的方法是执行此操作:

MyDomain.MyOtherDomains =
vm.MyOtherDomains.Select(o => new MyOtherDomain().InjectFrom(o))
.Cast<MyOtherDomain>();

编辑:
我做了一个新的测试项目,您可以下载(它也使用您的课程)。
在这里获取它: http://valueinjecter.codeplex.com/releases/view/60311 #DownloadId=318259

one quick and easy way would be to do this:

MyDomain.MyOtherDomains =
vm.MyOtherDomains.Select(o => new MyOtherDomain().InjectFrom(o))
.Cast<MyOtherDomain>();

edit:
I did a new test project that you can download (it uses your classes also).
get it here: http://valueinjecter.codeplex.com/releases/view/60311#DownloadId=318259

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文