2016-07-22 5 views
0

Derzeit bin ich hinzufügen die Eigenschaften und Werte zum Objekt manuell wie dieses Beispiel und Senden an Dapper.SimpleCRUD, um Daten von Dapper Orm zu holen. Dies ist der gewünschte Ausgang, den ich gerne erreichen würde.Dynamisch ein Objekt aus einer stark typisierten Klasse mit C# erstellen?

Die folgende Klasse sollte das Objekt im oben genannten Format erstellen und das fertige Objekt zurückgeben.

public static class WhereClauseBuilder 
{ 
    public static object BuildWhereClause(object model) 
    { 
     object whereObject = null; 
     var properties = GetProperties(model); 

     foreach (var property in properties) 
     { 
      var value = GetValue(property, model); 

      //Want to whereObject according to the property and value. Need help in this part!!! 
     } 

     return whereObject; 
    } 

    private static object GetValue(PropertyInfo property, object model) 
    { 
     return property.GetValue(model); 
    } 

    private static IEnumerable<PropertyInfo> GetProperties(object model) 
    { 
     return model.GetType().GetProperties(); 
    } 
} 

Diese Funktion WhereClauseBuilder.BuildWhereClause(object model) sollte das Objekt in erwarteten Format zurückkehren (mentiond oben). Hier ist die Implementierung von wie ich gerne verwenden würde.

public sealed class CountryModel 
{ 
    public int CountryId { get; set; } 
    public string CountryName { get; set; } 
    public string CountryCode { get; set; } 
    public bool IsActive { get; set; } 
} 

public class WhereClauseClass 
{ 
    public WhereClauseClass() 
    { 
     var model = new CountryModel() 
     { 
      CountryCode = "AOE", 
      CountryId = 2, 
      CountryName = "Anywhere on Earth", 
      IsActive = true 
     }; 

     //Currently, won't return the correct object because the implementation is missing. 
     var whereClauseObject = WhereClauseBuilder.BuildWhereClause(model); 
    } 
} 
+0

Dieser Link [http://msdn.microsoft.com/en-us/library/system.activator.creatinstance(VS.71).aspx](http://msdn.microsoft.com/en-us/ Bibliothek/system.activator.creatinstance (VS.71) .aspx) wird Ihnen helfen. – Thennarasan

+0

Danke, ich habe diesen Link gesehen. Aber, bin ich neugierig zu wissen, wie man das Objekt baut, das in einem gewünschten Format zurückgegeben werden kann? –

+0

Ich verstehe nicht genau, was Sie versuchen zu tun. Sie können eine Instanz von [ExpandoObject] (https://msdn.microsoft.com/de-de/library/system.dynamic.expandoobject (v = vs.110) .aspx) erstellen und sie mit dynamic verwenden, aber ich ' Ich bin mir nicht sicher, ob du das willst. Die andere Möglichkeit besteht darin, eine Codevorlage zu erstellen, die alle erforderlichen Namespaces und einen Klassenhauptteil enthält und die Eigenschaftsdefinitionen ausfüllt. Dadurch können Sie den Code zur Laufzeit kompilieren und eine Instanz Ihres Objekts erstellen. Microsoft.CSharp wird Ihnen in diesem Fall helfen. –

Antwort

1

Vielleicht so etwas wie folgt aus:

private const string CodeTemplate = @" 
    namespace XXXX 
    { 
     public class Surrogate 
     { 
    ##code## 
     } 
    }"; 

public static Type CreateSurrogate(IEnumerable<PropertyInfo> properties) 
{ 
    var compiler = new CSharpCodeProvider(); 
    var compilerParameters = new CompilerParameters { GenerateInMemory = true }; 
    foreach (var item in AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic)) 
    { 
     compilerParameters.ReferencedAssemblies.Add(item.Location); 
    } 

    var propertiesCode = 
     string.join("\n\n", from pi in properties 
          select "public " + pi.PropertyType.Name + " " + pi.Name + " { get; set; }"); 

    var source = CodeTemplate.Replace("##code##", propertiesCode); 

    var compilerResult = compiler.CompileAssemblyFromSource(compilerParameters, source); 
    if (compilerResult.Errors.HasErrors) 
    { 
     throw new InvalidOperationException(string.Format("Surrogate compilation error: {0}", string.Join("\n", compilerResult.Errors.Cast<CompilerError>()))); 
    } 

    return compilerResult.CompiledAssembly.GetTypes().First(x => x.Name == "Surrogate"); 
} 

Und jetzt ist es verwenden:

public static object BuildWhereClause(object model) 
{ 
    var properties = GetProperties(model); 
    var surrogateType = CreateSurrogate(properties); 
    var result = Activator.CreateInstance(surrogateType); 

    foreach (var property in properties) 
    { 
     var value = GetValue(property, model); 
     var targetProperty = surrogateType.GetProperty(property.Name); 
     targetProperty.SetValue(result, value, null); 
    } 

    return result; 
} 

ich nicht, dass kompilieren haben. Es ist nur hier geschrieben. Vielleicht gibt es ein paar Fehler. :-)

EDIT:

verwenden ExpandoObject Sie dies versuchen:

public static object BuildWhereClause(object model) 
{ 
    var properties = GetProperties(model); 
    var result = (IDictionary<string, object>)new ExpandoObject(); 

    foreach (var property in properties) 
    { 
     var value = GetValue(property, model); 
     result.Add(property.Name, value); 
    } 

    return result; 
} 

Aber ich weiß nicht, ob dies für Sie arbeiten.

+0

Ich wollte das 'ExpandoObject' vorschlagen und es in das Wörterbuch umwandeln, aber ich sehe, dass Sie es bereits zu Ihrem Update hinzugefügt haben. – Nkosi

+0

Danke Jungs. Ich denke, ich habe Probleme, 'ExpandoObject' in die gewünschte Ausgabe zu konvertieren, die ich möchte. Vielleicht gibt es einen Weg und ich weiß es nicht? –

+0

@CoderAbsolute Welchen Ausgabetyp benötigen Sie? Sie haben auch Probleme, das dynamisch erstellte Ersatzzeichen zu konvertieren. –