2008-11-24 19 views
15

Wie lösen "Muss MarshalByRefObject" in einer guten, aber mehrfacher Vererbung amputierten Sprache wie C#?Wie lösen "Muss MarshalByRefObject" in einer guten, aber mehrfacher Vererbung amputierten Sprache wie C#?

Das Problem ist sehr einfach, in einigen Fällen müssen Sie nur von dieser Klasse erben (Infrastrukturanforderungen). Es spielt hier keine Rolle, welche Fälle. Was tun Sie also, wenn Sie bereits von einer anderen Klasse geerbt haben (Ihre Domänenmodellanforderungen)?

Btw gute Anwendung Frameworks, wie Spring.net immer sicherstellen, dass Sie nicht von dieser Klasse erben müssen, egal welche Art von Infrastruktur Sie für Ihre Klasse anwenden müssen.

Ich würde gerne wissen, was bekomme ich -3 Stimmen hier für ?? :)

+0

Ich denke, man könnte hier mehr Kontext zu wissen, was das eigentliche Problem ist, zur Verfügung stellen müssen ... –

+0

+1 für das, was Greg sagte – JaredPar

+0

ich vermuten, dass Ihr -3 Stimmen ist für etwa einen die (jetzt bearbeitet) witzeln " amputierte Sprache mit Mehrfachvererbung ". Nicht alle sind sich einig, dass Mehrfachvererbung eine gute Idee ist. –

Antwort

14

Im Allgemeinen möchten Sie nur ein Objekt MarshalByRef erstellen, wenn Sie es in einem Remoting/WCF-Kontext verwenden möchten. Dies ist normalerweise ein Spezialfall, dass es kein Schmerz ist.

Angenommen, Sie hatten einen allgemeinen Typ, und Sie wollten daraus ableiten und spezialisieren, und dann remote den abgeleiteten Typ - jetzt haben Sie ein Problem, weil remoted ein Objekt von MarshalByRefObject und Ihrem ursprünglichen General erben muss Typ nicht. Angenommen, Sie können es nicht ändern, weil Sie eine binäre Vererbung durchführen, oder weil es selbst von einer Basisklasse abgeleitet ist, die Sie nicht ändern können? Da der Fragesteller darauf hinweist, dass C# (und .NET im Allgemeinen) MI nicht zulässt, können Sie nicht von beiden erben.

Die kurze Antwort ist, dass Sie irgendwie geschraubt sind. Sie ändern entweder den allgemeinen Typ von MarshalByRefObject in inert (oder gehen weit genug die Kette hinauf, dass Sie es irgendwo effektiv einfügen können), oder Sie können darüber nachdenken, sich mit Proxy-Objekten herumzuärgern.

Sie könnten beispielsweise einen Schnittstellenvertrag erstellen, der die Schnittstelle Ihres Typs beschreibt, und dann einen von MarshalByRefObject erbenen Proxy-Typ erstellen, der diese Schnittstelle ebenfalls durch Komposition und Delegierung in eine Instanz Ihres Typs (dh einen Wrapper) implementiert. Sie könnten dann eine Instanz dieses Proxy-Typs remote schalten, der Ihren Typ instanziieren und die Arbeit wie erwartet ausführen würde - aber alle Rückgabetypen von Methoden müssen [Serializable] sein.

public interface IMyType 
{ 
    string SayHello(); 
    string BaseTypeMethodIWantToUse(); 
} 

public class MyType : MyBaseType, IMyType 
{ 
    public string SayHello() 
    { 
     return "Hello!"; 
    } 
} 

public class MyRemoteableType : MarshalByRefObject, IMyType 
{ 
    private MyType _instance = new MyType(); 

    public string SayHello() 
    { 
     return _instance.SayHello(); 
    } 

    public string BaseTypeMethodIWantToUse() 
    { 
     return _instance.BaseTypeMethodIWantToUse(); 
    } 
} 

Scheint wie eine Menge Arbeit, obwohl. Letztendlich, wenn Sie in diesem Szenario sind, würde ich ein Redesign oder ein Umdenken vorschlagen.

+0

@DotNetGuy - danke für die tolle Antwort. – badbadboy

+0

leider, manchmal sind Sie mit einer 3rd-Party-API voller unmarshalable Typen fest :( –

+0

Ja, das tut saugen :-) –

1

Es hängt davon ab, wie Sie es bekommen müssen. Eine Basisklasse, die von MarshalByRefObject abgeleitet ist, könnte dies tun. Aggregation könnte es tun. Ohne ein konkreteres Beispiel für das, was Sie brauchen, ist es schwer zu sagen, aber es ist ein seltener Fall, dass Mehrfachvererbung die einzige Lösung für ein Problem wäre.

1

Sie können nicht von mehreren Klassen erben. Sie müssen entweder (a) Ihre Vererbungshierarchie ändern, damit die Basis von ihr erbt, oder (b) Ihre Anwendung anders schreiben.

Ohne weitere Informationen über warum müssen Sie von MarshalByRefObject erben oder warum Ihre Basisklasse nicht (nicht?), Dann ist es schwer, mehr konkrete Ratschläge zu geben.

Aber ich würde sagen, wenn Sie einen abgeleiteten Typ haben, der verschiedene Marshalling-Semantik zu seiner Basis benötigt, dann haben Sie wahrscheinlich ein Architekturproblem irgendwo.

+1

Der Ausdruck "mehrfache Vererbung amputierte Sprache" bestätigt, dass der Fragesteller versteht, dass Sie nicht von mehreren Klassen erben können. –

+0

@Aaron Palmer - das ist der Grund, warum ich zuerst Greg gewählt habe, aber das rückgängig gemacht habe, als er ein paar mehr Informationen hinzugefügt hat, die tatsächlich nützlich waren ...So, jetzt habe ich ihn gewählt :) – badbadboy

+1

Eigentlich sagt "Sprache" nicht vollständig, dass - es ist nicht die Sprache, die es verbietet, es ist das .NET Framework, das eine andere Sache ist. Daher war es wichtig zu erklären, dass es in .NET und nicht nur in C# überhaupt keine Mehrfachvererbung geben kann. –

0

"Was machst du also, wenn du bereits von einer anderen Klasse geerbt hast (deine Domain-Modell-Anforderungen)?"

Können Sie eine Basisklasse für das Teil Ihres Domänenmodells erstellen, für das eine Vererbung von MarshalByRefObject erforderlich ist?

0

Ich hatte Erfolg mit einem generischen Ansatz. T muss nicht "MarshalByRefObject" sein. Natürlich müssen Sie "RemoteProcess" durch das Objekt ersetzen, das Sie für das Remoting verwenden. Dann können Sie auf Ihr Nicht-MarshalByRefObject als RemotingHost.RemoteObject zugreifen.

public class RemotingHost<T> : MarshalByRefObject where T: class 
{ 
    RemoteProcess host; 
    T remoteObject; 
    public T RemoteObject { get { return remoteObject; } } 

    public RemotingAdmin() 
    { 
     host = new RemoteProcess(); 
     remoteObject = (T)host.CreateObject(typeof(T)); 
    } 
}