user5405648
user5405648

Reputation:

How can I get an instance of the parent class, the class that has initiated the current class when using object initialization?

I run in to this situation a lot. I'm finally seeking an answer on how I can do this. I understand that there are many ways, but most are dirty and include bad practices.

Just to make it clear, this is not asking for your opinion, it's asking how the majority of programmers deal with this kind of problem, pretty much any way possible that doesn't include really bad code.

I have a class called CoreContext, which I property inject new instances into the property's class names as show below. But what happens when I need the parent class that has initiated that class?

Say I need an instance of the CoreContext inside SocketHandler (ClientSocketHandler). How would I go about doing that? I feel like there's a really simple way, but I've never understood what that is.

Is there an even simple call stack I'm not seeing, or what? Note that I would prefer to do this, the way I am doing, Object initialization, and not assigning the properties later.

var coreContext = new CoreContext
{
    ConfigHandler = new JsonConfigHandler(),
    SocketHandler = new ClientSocketHandler(coreContext, IPAddress.Parse(""), 30),
    PacketProvider = new PacketProvider
    {
        Events = new Dictionary<short, Action<ICoreContext, IIncomingPacket>>
        {
            { IncomingPacketIds.AuthError, AuthErrorEvent.Process },
            { IncomingPacketIds.DeviceInformation, DeviceInformationEvent.Process },
            { IncomingPacketIds.AuthComplete, AuthCompleteEvent.Process },
        }
    }
};

Upvotes: 2

Views: 66

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109732

If you use constructor injection to pass a factory delegate to create the ClientSocketHandler you can circumvent this problem, but I'm not entirely sure that this is an improvement on simply setting the property after creation.

(Well, it is an improvement in that constructor injection is (IMO) better than propery injection.)

Anyway, here's an example in case it's of use to you.

Note the use of context => new ClientSocketHandler(context) to pass a factory delegate to the CoreContext constructor.

Then inside the CoreContext constructor you can pass this to the delegate.

using System;

namespace Demo
{
    class Program
    {
        public static void Main(string[] args)
        {
            var coreContext = new CoreContext(context => new ClientSocketHandler(context))
            {
                ConfigHandler = new ConfigHandler()
            };
        }

        class ConfigHandler {}

        class ClientSocketHandler
        {
            readonly CoreContext _coreContext;

            public ClientSocketHandler(CoreContext coreContext)
            {
                _coreContext = coreContext;
            }
        }

        class CoreContext
        {
            public CoreContext(Func<CoreContext, ClientSocketHandler> socketHandlerFactory)
            {
                SocketHandler = socketHandlerFactory(this);
            }

            public ClientSocketHandler SocketHandler { get; private set; }
            public ConfigHandler ConfigHandler { get; set; }
        }
    }
}

Note that if you use constructor injection, you can omit the setter for SocketHandler. Also note that you should be injecting via interfaces, but I've omitted that for brevity. I'm assuming that you don't want to new up an instance of ClientSocketHandler right there in the constructor!

Upvotes: 2

Related Questions