Frage

Ich habe eine Strategie bekommt für Typen von referenzierten DLLs zu lösen. Ich bin zu versuchen, zu lösen Typen fest, die in der Baugruppe definiert werden, die kompiliert wird. Ich verwende die System.Reflection.Emit apis ohne 3rd-Party-Bibliotheken.

Zum Beispiel:

class A {}
class B
{
    public A AnInstanceOfA {get; private set;}
}

Was ist der beste Weg zur Lösung B Referenz von A?

Was folgt aus:

class A
{
    B AnInstanceOfB {get; set;}
}
class B
{
    A AnInstanceOfA {get; set;}
}

, wo die Klassen enthalten Instanzen voneinander.

Gibt es einen Best-Practice-Weg, dies zu tun? Jegliche Designmuster ich umsetzen soll? Ich würde es vorziehen, nur die System.Reflection.Emit librarys zu verwenden, aber wenn es einen besseren Weg, dies zu tun oder dies kann nicht mit ihnen fertig wird, dann mit anderer Bibliothek (en) akzeptabel ist.

Danke

War es hilfreich?

Lösung

Könnten Sie auf die Frage erarbeiten, dass Sie laufen in (vielleicht Code ein kleines Beispiel-Code anzeigt, nicht für Sie arbeitet)? Da TypeBuilder ergibt sich aus Type, wenn Sie versuchen, sich gegenseitig rekursive Typen zu definieren, können Sie die beiden TypeBuilders passieren, wo Sie den Typen beziehen möchten.

Bearbeiten

Es gibt keine Notwendigkeit zu „lösen“ den Typen. Sie haben Zugriff auf die TypeBuilders für jeden und sie können einfach verwenden, als ob sie vollständig Typen definiert wurden. Hier ist ein Beispiel, das den Code generiert Sie in Ihrem Update angefordert:

private void DefineAutoProp(string name, Type t, TypeBuilder tb)
{
    var fldName = name.Substring(0, 1).ToLower() + name.Substring(1);
    var fld = tb.DefineField(fldName, t, FieldAttributes.Private);
    var prop = tb.DefineProperty(name, PropertyAttributes.None, t, null);
    var getter = tb.DefineMethod("get_" + name, MethodAttributes.Public, t, null);
    var ilg = getter.GetILGenerator();
    ilg.Emit(OpCodes.Ldarg_0);
    ilg.Emit(OpCodes.Ldfld, fld);
    ilg.Emit(OpCodes.Ret);
    var setter = tb.DefineMethod("set_" + name, MethodAttributes.Public, typeof(void), new[] { t });
    ilg = setter.GetILGenerator();
    ilg.Emit(OpCodes.Ldarg_0);
    ilg.Emit(OpCodes.Ldarg_1);
    ilg.Emit(OpCodes.Stfld, fld);
    ilg.Emit(OpCodes.Ret);
    prop.SetGetMethod(getter);
    prop.SetSetMethod(setter);
}

public void DefineTypes()
{
    var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test"), AssemblyBuilderAccess.Run);
    var mb = ab.DefineDynamicModule("test");
    var A = mb.DefineType("A", TypeAttributes.Public | TypeAttributes.Class);
    var B = mb.DefineType("B", TypeAttributes.Public | TypeAttributes.Class);
    DefineAutoProp("AnInstanceOfA", A, B);
    DefineAutoProp("AnInstanceOfB", B, A);
    A.CreateType();
    B.CreateType();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top