Comment résoudre & # 8220; Doit être MarshalByRefObject & # 8221; dans un langage amputé bon mais à héritages multiples comme C #?

StackOverflow https://stackoverflow.com/questions/313243

Question

Comment résoudre "Doit être MarshalByRefObject" dans un langage amputé bon mais à héritages multiples comme C #?

Le problème est très simple: dans plusieurs cas, vous devez simplement hériter de cette classe (configuration requise pour l’infrastructure). Peu importe ici vraiment, quels cas. Alors, que faites-vous si vous avez déjà hérité d'une autre classe (les exigences de votre modèle de domaine)?

Btw de bons frameworks d'application, comme spring.net, veillent toujours à ne PAS hériter de cette classe, quel que soit le type d'infrastructure à appliquer à votre classe.

J'aimerais savoir à quoi me servent -3 votes ici ?? :)

Était-ce utile?

La solution

En général, vous ne voulez créer un objet MarshalByRef que si vous envisagez de l’utiliser dans un contexte Remoting / WCF. C’est généralement un cas assez spécial pour que ce ne soit pas une douleur.

Supposons que vous ayez un type général et que vous vouliez en tirer et le spécialiser, puis éloignez le type dérivé. Vous rencontrez maintenant un problème car un objet doit hériter de MarshalByRefObject et son type général d'origine n'a pas. Supposons que vous ne puissiez pas le changer parce que vous faites un héritage binaire ou parce qu'il dérive d'une classe de base que vous ne pouvez pas changer. Comme le remarque l'interlocuteur, puisque C # (et .NET en général) n'autorise pas MI, vous ne pouvez pas hériter des deux.

La réponse courte est que vous êtes un peu foutu. Vous pouvez changer le type général hérité de MarshalByRefObject (ou aller assez loin dans la chaîne pour pouvoir l'insérer dans un endroit efficace), ou bien vous pouvez envisager de manipuler des objets proxy.

Vous pouvez par exemple créer un contrat d'interface décrivant l'interface de votre type, puis créer un type de proxy héritant de MarshalByRefObject qui implémente également cette interface par composition et délégation à une instance de votre type (un wrapper). Vous pouvez alors distant une instance de ce type de proxy qui instancierait votre type et effectuerait le travail comme prévu - mais tous les types de retour des méthodes doivent être [Serializable].

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();
    }
}

Cela semble être beaucoup de travail, cependant. En fin de compte, si vous êtes dans ce scénario, je suggérerais une refonte ou une refonte.

Autres conseils

Cela dépend de la façon dont vous devez y arriver. L'utilisation d'une classe de base dérivée de MarshalByRefObject pourrait le faire. L'agrégation pourrait le faire. Sans un exemple plus concret de ce dont vous avez besoin, c'est difficile à dire, mais il est rare que l'héritage multiple soit la seule solution à un problème.

Vous ne pouvez pas hériter de plusieurs classes. Vous devez donc soit (a) modifier votre hiérarchie d'héritage pour que la base en hérite, soit (b) écrire votre application différemment.

Sans plus d'informations sur pourquoi , vous devez hériter de MarshalByRefObject ou pourquoi votre classe de base ne le fait pas (impossible?), il est donc difficile de donner des conseils plus concrets.

Mais je dirais que si vous avez un type dérivé qui nécessite une sémantique de marshaling différente de celle de base, vous avez probablement un problème d'architecture quelque part.

"Alors, que faites-vous si vous avez déjà hérité d'une autre classe (les exigences de votre modèle de domaine)?"

Pouvez-vous créer une classe de base pour l'élément de votre modèle de domaine nécessitant l'héritage de MarshalByRefObject?

J'ai eu du succès avec une approche générique. Il n'est pas nécessaire que T soit "MarshalByRefObject". Bien entendu, vous devrez remplacer " RemoteProcess " avec l'objet que vous utilisez pour l'accès distant. Ensuite, vous pouvez accéder à votre non-MarshalByRefObject en tant que RemotingHost.RemoteObject.

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));
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top