Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve "Must be MarshalByRefObject" in a good but multiple-inheritance amputated language like C#?

How to solve "Must be MarshalByRefObject" in a good but multiple-inheritance amputated language like C#?

The problem is very simple, in several cases you just have to inherit from this class (infrastructure requirements). It does not matter here really, which cases. So, what do you do if you've already inherited from some other class (your domain model requirements)?

Btw good application frameworks, like spring.net always make sure you DON'T have to inherit from this class no matter what kind of infrastructure you need to apply to your class.

I would like to know what am I getting -3 votes here for?? :)

like image 614
Paul Kapustin Avatar asked Nov 24 '08 01:11

Paul Kapustin


3 Answers

In general you only want to make an object MarshalByRef if you're going to use it in a Remoting / WCF context. This is usually a special-enough case that it's not a pain.

Suppose you had a general type, and you wanted to derive from it and specialise it, and then remote the derived type - now you have a problem, because to be remoted an object must inherit from MarshalByRefObject, and your original general type didn't. Suppose you can't change it because you're doing binary inheritance, or because it itself derives from a base class you can't change? As the questioner points out, since C# (and .NET in general) doesn't allow MI, you can't inherit from both.

The short answer is that you're sort-of screwed. You either change the general type to inhert from MarshalByRefObject (or go far enough up the chain that you can insert it somewhere effective), or else you can think about mucking about with proxy objects.

You could for example create an interface contract that describes your type's interface, and then build a proxy type inheriting from MarshalByRefObject that also implements that interface by composition and delegation to an instance of your type (ie a wrapper). You could then remote an instance of that proxy type which would instantiate your type and do the work as expected - but all return types from methods have to be [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();
    }
}

Seems like a lot of work, though. Ultimately if you're in this scenario I'd suggest a redesign or a rethink.

like image 151
Neil Hewitt Avatar answered Oct 04 '22 09:10

Neil Hewitt


It depends on how you need to get at it. Using a base class that derives from MarshalByRefObject might do it. Aggregation might do it. Without a more concrete example of what you need it's hard to say, but it's a rare case that multiple inheritance would be the only solution to a problem.

like image 32
ctacke Avatar answered Oct 04 '22 10:10

ctacke


You can't inherit from multiple classes. So you either need to (a) change your inheritance hierarchy so the base inherits from it, or (b) write your application differently.

Without more information about why you need to inherit from MarshalByRefObject or why your base class does not (cannot?) then it's hard to give any more concrete advice.

But I'd say if you have a derived type that needs different marshaling semantics to its base, then you've probably got an architectural issue somewhere.

like image 41
Greg Beech Avatar answered Oct 04 '22 10:10

Greg Beech