1

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?

2
  • 2
    Why are you using dynamic at all? If you're doing everything with reflection, I can't see that you're actually doing anything that makes use of it being dynamic. Commented Jun 20, 2013 at 7:22
  • Sorry, I don't know much about Reflection namespace. Commented Jun 20, 2013 at 7:25

2 Answers 2

3

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;
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I'm not copying properties. Now the values are just hard-coded as given in the question. I'm just trying to decouple two assemblies.
@SenJacob maybe investigate automapper?
@SenJacob: Well what are you trying to do? If you're going to "assign the property prop.Name to obj" you need to have a value... what value do you want? Your comment says: "assign the properties and corresponding values to newly created object" - in what way is that not copying properties?
@JonSkeet Sorry for my bad English.. I meant that I'm not copying properties of another object I already have. the properties and values are given as a dynamic object like new { UserID = 0, Name = "user abc", LoginCode = "abc", DefaultPassword = "xxxxxx" }
@SenJacob that is not a "dynamic object"; that is an instance of an anonymous type, which is actually a regular static-typed class; the only interesting things about it are that a: we don't create the class ourselves (the compiler does), and b: we do not know the type-name
|
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.