Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to share a property amongst several C# classes

Tags:

c#

asp.net

I have several classes which inherit from different classes. All those classes have a session property (which they define or inherit).

I'd like to add a property to all those classes :

public SessionObject SessionObject
{
    get
    {
        return Session["SessionObject"] as SessionObject;
    }
    set
    {
        Session["SessionObject"] = value;
    }
}

But I don't see how.

I think in C++ I could just use a template, but I don't see Generics doing that.

How can it be done?

like image 887
Serge Profafilecebook Avatar asked Dec 11 '14 10:12

Serge Profafilecebook


2 Answers

You have a finite number of options for sharing the implementation across multiple types

  1. If all your objects share a common base class already, add it there. If they do not use inheritance at all, you could define a base class - however C# allows only one implemenation inheritance

  2. Use composition, this involves writing a class with just your property and having that property on all classes (see example 1)

  3. Use extension methods - you could do this on a "marker" interface (with no actual methods) or on the objects themselves (see example 2)


Example 1

public class SessionContainer
{

    public SessionObject SessionObject
    {
        get
        {
            return Session["SessionObject"] as SessionObject;
        }
        set
        {
            Session["SessionObject"] = value;
        }
    }
}

public class YourClass1
{
    public SessionContainer Session { get; private set; }

    public YourClass1
    {
        this.Session = new SessionContainer();
    }
}

public class YourClass2
{
    public SessionContainer Session { get; private set; }

    public YourClass2
    {
        this.Session = new SessionContainer();
    }
}

Example 2 (using a marker interface which is empty)

public interface ISessionContainer{}

public static class SessionExtensions
{
    public static SessionObject GetSessionObject(this ISessionContainer session)
    {
        return session["SessionObject"] as SessionObject;
    }

    public static void SetSessionObject(this ISessionContainer session, 
                                                SessionObject obj)
    {
        session["SessionObject"] = obj;
    }

}

public class YourClass1 : ISessionContainer{}
public class YourClass2 : ISessionContainer{}
like image 71
Jamiec Avatar answered Sep 29 '22 09:09

Jamiec


A couple of options (assuming you can't just make an abstract class and use it as a base class for everything).

Use an interface and a pair of extension methods:

public interface IHasSession
{
    public Session Session { get; set; }
}

public static class HasSessionExtensions
{
    public static void SetSessionObject(this IHasSession subject, SessionObject value)
    {
        subject.Session["SessionObject"] = value;
    }

    public static SessionObject GetSessionObject(this IHasSession subject)
    {
        return subject.Session["SessionObject"] as SessionObject;
    }
}

Or use a wrapper class for your session:

public class SessionWrapper
{
    public Session Session { get; set; }

    public SessionObject SessionObject
    {
        get
        {
            return Session["SessionObject"] as SessionObject;
        }
        set
        {
            Session["SessionObject"] = value;
        }
    }
}

And put that on your other classes instead:

public SessionWrapper SessionWrapper { get; set; }

Then you only need to implement it once and can access it via:

var obj = myThing.SessionWrapper.SessionObject;
like image 30
Ant P Avatar answered Sep 29 '22 09:09

Ant P