akadian akadian - 2 years ago 70
C# Question

Storing an object in dictionary without calling constructor

I currently have an interface for detectors, which is called "Model". In my factory class, I have this function called CreateDetector, which returns the appropriate Model of the detector.

public Detector CreateDetector(string modelName, string ip, string port) {
if ( modelName = "A" )
{
return new ModelA(ip, port);
}
if ( modelName = "B" )
{
return new ModelB(ip, port);
}
...
}


To me, this seems rather inefficient and the code is repeated multiple times. In scenarios similar to this, I would normally use the following approach.

public Detector CreateDetector(string modelName, string ip, string port) {
Dictionary<string, Detector> detectors = new Dictionary<string, Detector>()
{
{ "A", new ModelA(ip, port) },
{ "B", new ModelB(ip, port) },
...
};
return detectors[modelName]
}


However, in the current implementation of Detector, the base constructor always calls Init(), which attempts to connect to the devices. Obviously, I do not want to connect X amount of times to the device, as this could cause a multitude of issues. (This part is what got me to ask the question, I understand a constructor should not be heavy, but this is legacy code which will not be changed.)

I would like the end result to simulate something like this, where the dictionary just contains a declaration of the object, but the constructor is only called once it is determined which class you are using.

public Detector CreateDetector(string modelName, string ip, string port) {
Dictionary<string, Detector> detectors = new Dictionary<string, Detector>()
{
{ "A", ModelA(ip, port) },
{ "B", ModelB(ip, port) },
{ "C", ModelC(ip, port) },
...
{ "X", ModelX(ip, port) },
};
if (modelName = "B" || modelName = "C")
{
//special case for these 2 models
}
return new detectors[modelName]
}


What I am trying to accomplish is stopping the recurring "if/else" which are all identical, but without the initialization of the constructor until I request its value.

Answer Source

i would have the following static field in your class:

static Dictionary<string, Func<string, string, Detector>> _detectors = new Dictionary<string, Func<string, string, Detector>>()
{
    { "A", (ip, port)=> new ModelA(ip, port) },
    { "B", (ip, port)=> new ModelB(ip, port) }
};

The value of the dictionary is a object factory method:

var factory = _detectors[modelName];  // returned type is Func<string, string, Detector>
var result = factory(ip, port);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download