- An Open Source Free product
- It's a Mapper
- It lets you define your own convention-based matching algorithms (ValueInjections)
- In order to match up (inject) Source values to Destination values
- With the ValueInjecter you inject values from the properties of source into properties of target object using ValueInjections
- Each ValueInjection has it's own conventions of which properties to match and how to transform the value.
- By Default maps the properties with the Same Name and Same Type
- But you can override TypesMatch to change this from source to the ones in the target
When To Use ?
- When we need to Map Domain Model to ViewModel and Vice-versa
How to Download?
- You can download the "Omu.ValueInjecter.dll" from CodePlex located Here
How to Set Reference for above .dll on Your Project ?
- On your Web Project Add Reference to the "Omu.ValueInjecter.dll"
Let's Try with Simple Example
- C# , MVC 3 and Visual Studio 2010 has been used.
- Please Follow an Inline Comments on Code.
- Simple application with Product Name text box,Retail Price text box and Save button.
Our Domain Model Looks like below
public class Product
{
public Product() { Id = Guid.NewGuid() //create Guid as Primary key }
public Guid Id { get; set; }
public string ProductName { get; set; }
public decimal RetailerPrice { get; set; }
public virtual Provider Provider { get; set; }
}
Our ViewModel Looks like below
public class ProductViewModel
{
public Guid Id { get; set; }
[Required(ErrorMessage = "required")]
public string ProductName { get; set; }
[Required(ErrorMessage = "required")]
public decimal RetailerPrice { get; set; }
}
Our Controller Looks like below
[HttpPost]
public ActionResult AddProduct(ProductViewModel productViewModel, string providerKey)
{
//get provider from repository
var provider = Repository.GetProvider(providerKey);
//create Product domain object
var productObj = new Product();
//usage of ValueInjecter
//source object as productViewModel
//target object as productObj
//type 'FilterId' for keep target property 'Id' value
//not overridden from source property 'Id' value (will explain later)
productObj.InjectFrom<FilterId>(productViewModel);
//If something missing then map as below
productObj.Provider = provider;
if (ModelState.IsValid) //check validation
{
//save for repository
Repository.AddProduct(productObj);
return RedirectToAction("AddProduct", new { providerKey = providerKey });
}
else
{
return View(productViewModel);
}
}
Our FilterId Custom Class Looks like below
using Omu.ValueInjecter;
namespace PawLoyalty.Web.Areas.Providers.ValueInjections
{
public class FilterId : LoopValueInjection
{
//sourcePropName "Id" will not map to target property name "Id"
//ie: Keep target property value as it is (not change from mapping)
protected override bool UseSourceProp(string sourcePropName)
{
return sourcePropName != "Id";
}
}
}
Why We Need 'FilterId' Custom Class ?
# It's a Custom class inherited from LoopValueInjection class
# On our Domain Model (Product) we have to Initialize property Id of type Guid when creates
an object (inside a constructor) as a Primary Key.
# So After that generated Id will save on the Database at the end
# When we use productObj.InjectFrom(productViewModel) Line of code (default)
Without <FilterId> then source object (productViewModel) will override the
target object's Id with value {00000000-0000-0000-0000-000000000000}.
# So for avoid such a situation we have to use FilterId Custom class as above
# i.e When we need to keep without changing target property Id value (productObj).
Because it is our Primary key.
Because it is our Primary key.
What Says Creator of ValueInjecter ? - By Valentin Plamadeala
Another way of doing the FilterId injection would be like this:
Method 1:
public class FilterId : ConventionInjection
{
protected
override bool
Match(ConventionInfo c)
{
return
c.SourceProp.Name != "Id"
&& c.SourceProp.Name == c.TargetProp.Name
&&
c.SourceProp.Type == c.TargetProp.Type;
}
}
public class IngnoreProps : ConventionInjection
{
private
readonly string[]
_ignores;
public
IngnoreProps()
{
}
public
IngnoreProps(params string[]
ignores)
{
_ignores = ignores;
}
protected
override bool
Match(ConventionInfo c)
{
return
(_ignores == null ||
!_ignores.Contains(c.SourceProp.Name)) &&
c.SourceProp.Name == c.TargetProp.Name
&& c.SourceProp.Type
== c.TargetProp.Type;
}
}
target.InjectFrom(new
IgnoreProps("Id"), source);
Special Thanks
I must put special thanks for Valentin Plamadeala (Creator of ValueInjecter) who gave me a feedback for my Article and also put that on codeplex. Thanks Valentin.I hope you will create lots of this kind of value added components behalf of us in future also.Good Luck.
Special Thanks
I must put special thanks for Valentin Plamadeala (Creator of ValueInjecter) who gave me a feedback for my Article and also put that on codeplex. Thanks Valentin.I hope you will create lots of this kind of value added components behalf of us in future also.Good Luck.
What are the Features of ValueInjecter ?
- It's Simple and Very Flexible
- It's something like mozilla with it's plugins, you create ValueInjections and use them
- There are built-in injections for flattening, unflattering
- Can use with MVC ,Win-Forms,Web-Forms,Silverlight,WPF and Data Access Situations
- Can also use ValueInjecter to map from Anonymous and Dynamic objects
- Valueinjecter has a default injection .InjectFrom() that does the properties with the Same Name and Same Type.
- For everything else you can Create your Custom Valueinjections with individual mapping logic/rules, more like aspects. e.g. from all properties of Type Foo to all properties of type Bar
What is Aspects - Aspect Oriented Programming (AOP) involves breaking down
program logic into distinct parts.
Do you need to Dive Deep ends of ValueInjecter ?
- Documentation Here
- Discussions Here
- Stackoverflow Here
Conclusion
- Above I have showed very simple usage of ValueInjecter Mapper
- If you need to learn more about ValueInjecter then you have to follow above mentioned Links
- This mapper is nicely fit with Asp.Net MVC ViewModel developments for very simple to very complex scenarios
I hope this helps to You.Comments and feedback greatly appreciated.
Happy Coding.
Happy Coding.
Related Article
NIce blog youhave !!!! use this plugin for coding http://dedunu.info/2012/09/24/live-writer-and-t-sql/ it will nice to your blog!!!!
ReplyDeleteHi Dedunu,
DeleteYes sure.I will try and let you know.
Thanks for your feedback.
Hello,
ReplyDeleteWhy you don't use standard mappers like AutoMapper or AutoMapper? With profit can give your own mapper?
-Oleg Maslovsky-
Hi Oleg,
DeleteI am new to the Mapper world.But I did R&D about mappers and then I have decided to use ValueInjecter as my mapping tools because of below mentioned reasons
1. Its very simple and flexible (easy to customize)
2. there are built-in injections
for flattening,unflattering, and some that
are intended to be inherited and it works
more in an aspect type (AOP) of way
3. ValueInjecter is used even in windows
forms with flattening and unflattering
> Those are the interesting points I have notice
about ValueInjecter.
> Some of them cannot do by using
Auto mapper(e.g.unflattering)
> And also ValueInjecter has been introduced
new Injection as for Maximum performance
with the SmartConventionInjection.
> You can get those details from here :
http://valueinjecter.codeplex.com/wikipage? title=SmartConventionInjection
like this.
ReplyDelete-Mesut Darvishian-
Hi Mesut,
DeleteThanks for your response.
Do Keep in Touch.
like this.
ReplyDelete-Peter Ernst-
Hi Peter,
DeleteThanks for your feedback.
Do Keep in Touch.
Hi,
ReplyDeleteExcellent article, crystal clear explanations.
I am new to AutoMapper and ValueInjecter.
In my project I am handling this same scenario by using extension methods.
But that method is more restricted one not having more features. Simply it will convert the properties from source to destination(Name and data type should be same).
Below I mentioned the code snippet.
public static D ConvertToAsChild(this S source, D Destination)
{
foreach (PropertyInfo item in source.GetType().GetProperties())
{
if (Destination.GetType().GetProperty(item.Name) != null &&
Destination.GetType().GetProperty(item.Name).PropertyType.IsAssignableFrom(item.PropertyType))
{
Destination.GetType().GetProperty(item.Name).SetValue(Destination, item.GetValue(source, null), null);
}
}
return Destination;
}
Surely I will explore and implement this tools in my project.
Thanks to author.
- Added -
Deletepublic static D ConvertTo(this T source, D Destination)
{
foreach (PropertyInfo item in Destination.GetType().GetProperties())
{
item.SetValue(Destination, source.GetType().GetProperty(item.Name).GetValue(source, null), null);
}
return Destination;
}
Hi Mukesh,
DeleteThanks for your appreciation.
Yes Actually you can use ValueInjecter for your project also.It's very simple and easy to customize.
You can get lot of details by using above mentioned links
on my article.
They have introduced very high performance new injecter also.Please Check below mentioned link for more details.
# Maximum performance with the SmartConventionInjection
http://valueinjecter.codeplex.com/wikipage?title=SmartConventionInjection&referringTitle=Home
--- Via G+ ---
ReplyDeleteGood Article machan. I have use auto mapper before seems value injector much better than auto mapper. How is your experience with value injector. have u been use this in commercial project.
-Mahesh Milinda-
Hi Mahesh,
DeleteYep, ValueInjector is much better than the Auto mapper.But in my projects I have not used any of the Mapper Tools yet.I did this article as a R&D project.So I would like to recommend VI for your next project.Hence It's very easy to learn and also will give better performances.