mardi 23 mai 2017

How to create class from string, register and then resolve using unity

I'm using C#, WPF, Prism 6.3 and using Unity as an IoC container.

Here's one part I don't quite understand and could use some clarity.

Scenario: My application will talk to multiple physical lasers. I created a LaserModule with Views/Viewmodels, as well as ILaser interface, and 3+ brand-specific laser classes (LaserA/B/C). Since all the Lasers have the same functionality (Connect, GetReading, Disconnect) I thought it was a good idea to make the ILaser interface so they all must implement these methods, but in whatever way they need to.

Furthermore, the module will read from a laser.cfg file and in that file it will have the settings for each laser, including the "Class" of the laser which I will use to instantiate the proper laser class with.

The overall idea is that the LaserModule will create however many lasers are in the config file, of the appropriate type, and then register them in a unity container so they can be access throughout other parts of the application. In the other parts of my application, the goal is that the programmer shouldn't need to know anything about the particular laser or specific class, instead just work using the interface. The interfaces will all be stored in a common module, so that should be the only dependency.

This is where I'm at now... and it appears to be working because when the .Greet() methods are called at the end, I see the greeting that I gave when using Activator.CreateInstance.

Is this approach realistic or am I totally missing the point?

namespace LaserModule
{
    interface ILaser
    {
        void Greet();
    }
}


namespace LaserModule
{
    class LaserA: ILaser
    {

        private string greeting = "blank";

        public LaserA(string greet)
        {
            this.greeting = greet;
        }

        public void Greet()
        {
            MessageBox.Show("LaserA - " + greeting);
        }
    }
}

public void Initialize()
{

    //Create Laser objects based on what brand of laser is supplied
    String className = ReadLaserClassNameFunc1();
    Type t = Type.GetType("LaserModule." + className, true);
    object t2 = (Activator.CreateInstance(t,"laser 1 greeting"));
    ILaser myLaser1 = (ILaser)t2;

    //Create Laser objects based on what brand of laser is supplied
    className = ReadLaserClassNameFunc2();
    t = Type.GetType("LaserModule." + className, true);
    object t2 = (Activator.CreateInstance(t,"laser 2 greeting"));
    ILaser myLaser2 = (ILaser)t2;

    //Create Laser objects based on what brand of laser is supplied
    className = ReadLaserClassNameFunc3();
    t = Type.GetType("LaserModule." + className, true);
    object t2 = (Activator.CreateInstance(t,"laser 3 greeting"));
    ILaser myLaser3 = (ILaser)t2;


    _unityContainer.RegisterInstance("Laser1", myLaser1, new ContainerControlledLifetimeManager());
    _unityContainer.RegisterInstance("Laser2", myLaser2, new ContainerControlledLifetimeManager());
    _unityContainer.RegisterInstance("Laser3", myLaser3, new ContainerControlledLifetimeManager());

    ...
    //The following lines would in reality be called from a different assembly.

    ILaser theLaser1 = _unityContainer.Resolve<ILaser>("Laser1");
    ILaser theLaser2 = _unityContainer.Resolve<ILaser>("Laser2");
    ILaser theLaser3 = _unityContainer.Resolve<ILaser>("Laser3");

    theLaser1.Greet();
    theLaser2.Greet();
    theLaser3.Greet();

}





Aucun commentaire:

Enregistrer un commentaire