Reputation: 3452
I'm trying to write a function which creates an object of Type t and assign its properties.
internal static object CreateInstanceWithParam(Type t, dynamic d)
{
//dynamic obj = t.GetConstructor(new Type[] { d }).Invoke(new object[] { d });
dynamic obj = t.GetConstructor(new Type[] { }).Invoke(new object[] { });
foreach (var prop in d.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
//prop.Name,
//prop.GetValue(d, null);
// assign the properties and corresponding values to newly created object ???
}
return obj;
}
Then I should be able to use this for any kind of class types like
IUser user = (IUser)CreateInstanceWithParam(userType, new { UserID = 0, Name = "user abc", LoginCode = "abc", DefaultPassword = "xxxxxx" });
IUnit newUnit = (IUnit)CreateInstanceWithParam(unitType, new { ID = 3, Code = "In", Name = "Inch", Points = "72" })
How can I assign the property prop.Name
to obj
?
Upvotes: 1
Views: 2740
Reputation: 1063884
Actually, using dynamic
would probably be a bad thing here; the objects you are passing in are instances of anonymous types - no need for dynamic
. In particular, dynamic
member access is not the same as reflection, and you cannot guarantee that an object described as dynamic
will return anything interesting from .GetType().GetProperties()
; consider ExpandoObject
, etc.
However, FastMember
(available on NuGet) may be useful:
internal static object CreateInstanceWithParam(Type type, object template)
{
TypeAccessor target = TypeAccessor.Create(type),
source = TypeAccessor.Create(template.GetType());
if (!target.CreateNewSupported)
throw new InvalidOperationException("Cannot create new instance");
if (!source.GetMembersSupported)
throw new InvalidOperationException("Cannot enumerate members");
object obj = target.CreateNew();
foreach (var member in source.GetMembers())
{
target[obj, member.Name] = source[template, member.Name];
}
return obj;
}
In particular, this can use the dynamic
API just as easily as the reflection API, and you never usually see the difference.
Upvotes: 1
Reputation: 1503140
Assuming you're just trying to copy properties, you don't need dynamic
at all:
internal static object CreateInstanceWithParam(Type type, object source)
{
object instance = Activator.CreateInstance(type);
foreach (var sourceProperty in d.GetType()
.GetProperties(BindingFlags.Instance |
BindingFlags.Public))
{
var targetProperty = type.GetProperty(sourceProperty.Name);
// TODO: Check that the property is writable, non-static etc
if (targetProperty != null)
{
object value = sourceProperty.GetValue(source);
targetProperty.SetValue(instance, value);
}
}
return instance;
}
Upvotes: 3