2016-07-08 13 views
2

Ich habe die folgende Klasse, die ich Entity Framework Model übergeben, wenn Sie eine Instanz davon machen.Wie kann ich eine neue Instanz einer Klasse zur Laufzeit mit C# erstellen?

public class TableMapper<TSource> 
{ 
    protected IQueryExtractor QueryExtractor { get; set; } 
    protected string TableAliasPrefix { get; private set; } 

    public TableMapper(IQueryExtractor queryExtractor, string tableAliasPrefix = null) 
    { 
     QueryExtractor = queryExtractor; 
     TableAliasPrefix = tableAliasPrefix; 
    } 

    public IReportRelation GetForeignRelation<TProperty>(Expression<Func<TSource, TProperty>> property) 
    { 
     return new ReportRelation 
     { 
      Column = GetReportColumn(null, Self, property), 
      TableName = this.Table(), 
      TableAlias = this.GetSqlAlias(), 
      ModelType = typeof(TSource), 
      QueryExtractor = this.QueryExtractor 
     }; 
    } 

    ... 
    ... 
    ... 
} 

Ich nenne dies noch oben Klasse von einer anderen Klasse wie so

var clientMapper = new TableMapper<Client>(QueryExtractor, "Client"); 
var = clientMapper.GetForeignRelation(x => x.Id); 

Bitte beachten Sie, dass Client ist ein Entity Framework 6-Modell.

von innerhalb meiner GetForeignRelation Methode, habe ich die Art der Client oder <TSource> so kann ich zur Laufzeit eine neue Instanz der Klasse TableMapper erstellen.

Hier ist, was ich versucht habe zu versuchen, eine neue Instanz zur Laufzeit zu erstellen.

var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType); 
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias); 

Aber das gibt mir einen Fehler.

Der Typ oder Namespace-Namen RunTimeModel konnte nicht gefunden werden (sind Sie eine using-Direktive oder ein Assemblyverweis fehlt?)

Wie kann ich eine neue Instanz der gleichen Klasse zur Lauf korrekt erstellen Zeit?

Antwort

1

Sie die Klassennamen TSource bekommen mit

typeof(TSource).Name 

sollten Sie in der Lage sein, eine Instanz mit zu erstellen:

var instance = Activator.CreateInstance(typeof(TSource)); 

solange der Typ in der gleichen Baugruppe ist Andere Eigenschaften kann verwendet werden, um den vollständigen Namensraum zu erhalten

EDIT:

Gilt dieses Beispiel für Ihren Scanario? Hatte Ihre bereitgestellten Code auszuziehen, da ich nicht weiß, was dahinter ist alles :)

class Program 
{ 
    static void Main(string[] args) 
    { 
     var test = new TableMapper<A>(); 
     var fr = test.GetForeignRelation(); 
     var type = fr.ModelType; 
     var newInstance = Activator.CreateInstance(type); 
    } 
} 

public class TableMapper<TSource> 
{ 

    public TableMapper() 
    { 
    } 

    public ReportRelation GetForeignRelation() 
    { 
     return new ReportRelation 
     { 
      ModelType = typeof(TSource) 
     }; 
    } 
} 

public class ReportRelation 
{ 
    public Type ModelType { get; set; } 
} 

public class A 
{ 
    public string Test { get; set; } 
    public A() 
    { 
     Test = "Some string"; 
    } 
} 
+0

Ich speichere 'typeof (TSource)' in eine Variable 'relationsMapping.ForeignRelation.ModelType' wie können Sie in meinem Code. dann übergebe ich das an die 'Activator.CreateInstance()', aber es funktioniert nicht für mich.Bitte beachten Sie den Fehler in meiner Frage – Jaylen

+0

Ich verwende Fall ist ähnlich wie Sie codiert. Ich muss also eine Instanz von 'ReportRelation' erstellen. Bitte beachten Sie, dass' 'ein Entity Framework-Modell ist. – Jaylen

0

Sie nicht Variable auf einen Typparameter

var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType); 
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias) 

Da RunTimeModel kein Typ passieren kann, ist aber ein Variable. Ich denke, dass Sie den Zweck der Methode vermissen, die Sie verwenden.

+0

Ich bin mir nicht sicher, ob ich weiß, was Sie in meinem Code ändern wollen – Jaylen

0

können Sie den folgenden Code verwenden, um Ihre generischen Typ zu instanziiert:

var RunTimeMapper = Activator.CreateInstance(typeof(TableMapper<>).MakeGenericType(new[] { relationsMapping.ModelType }), new[] { relationsMapping.QueryExtractor, relationsMapping.TableAlias }); 

Allerdings ist der Rückgabewert Typ für RunTimeMapper object.I cann't herauszufinden, wie RunTimeMapper seiner tatsächlichen type.So werfen Es ist ein wenig unbequem zu benutzen.

Referer: How to: Examine and Instantiate Generic Types with Reflection

Verwandte Themen