سؤال

In my project, I have a service class.

class KLAService : IKLAService
{
    CentralLogic centralLogic;

    .....
}

Using this class, I set up the ServiceHost like this:

centralLogic = new CentralLogic();

ServiceHost host = new ServiceHost(typeof(KLAService));
using (host)
{ 
    host.Open();

    Application app = new Application();
    app.Run(new ConfigurationWPF.MainWindow(centralLogic));

    host.Close();
}

As it might have become clear, I create one instance of the CentralLogic class. This very instance is used in the UI but also in the host to manage other stuff in my solution.

The problem I'm having now, is to set the centralLogic-variable in the KLAService-class (or in the host). I don't know how to do this. I've read about the plugin Ninject and how to inject objects in the service, but that's way out of my league and I can't help but think there is an easy way.

How can I achieve my goal the best?

EDIT: Another solution proposed was to start the ServiceHost and let CentralLogic get created there instead of the other way around. That would mean the ServiceHost needs some sort of a constructor. I don't know what the best practice is nor how to achieve this. Any help is appreciated.

هل كانت مفيدة؟

المحلول

I don't think you really need dependency injection. Since CentralLogic has a single instance, it is effectively a singleton. Read about singleton pattern here.

You can implement the singleton pattern on CentralLogic

public sealed class CentralLogic
{
    private static readonly Lazy<CentralLogic> lazy =
        new Lazy<CentralLogic>(() => new CentralLogic());

    public static CentralLogic Instance { get { return lazy.Value; } }

    private CentralLogic()
    {
    }
}

Then in the Service Impl's contructor (and in the UI), you get the instance, this way:

class KLAService : IKLAService
{
    CentralLogic m_centralLogic;

    public KLAService() 
    {
       m_centralLogic = CentralLogic.Instance;
       ....
    }
}

There is no need to pass anything to ServiceHost.

The most important thing for you here is make sure your CentralLogic's instance is thread safe.

نصائح أخرى

The simplest solution is to create a singleton for the CentralLogic class.

If you want to do dependency injection, I would recommend structuremap and you can set it up pretty easily with nuget and I'd advice for you to do the injection in the KLAService

Here's a console app that shows how to set it up and inject some local object to other classes:

class KLAService : IKLAService
{
    // Constructor injection
    public KLAService(ICentralLogic logic)
    {
        Console.WriteLine(logic.Value);
    }

    // Manual instance creation
    internal void PrintLogicValue()
    {
        var logic = ObjectFactory.Container.GetInstance<ICentralLogic>();
        Console.WriteLine(logic.Value);
    }
}

interface IKLAService
{
}

class CentralLogic : ICentralLogic
{
    public int Value { get; set; }

    public CentralLogic()
    {
        Value = 12345;
    }
}

interface ICentralLogic
{
    int Value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var logic = new CentralLogic();

        ObjectFactory.Initialize(x => x.Scan(scan => scan.TheCallingAssembly()));
        ObjectFactory.Container.Configure(x => x.For<ICentralLogic>().Use(y => logic));

        var service = ObjectFactory.Container.GetInstance<KLAService>();
        service.PrintLogicValue();

        Console.ReadKey();
    }
}

When the code calls var service = ObjectFactory.Container.GetInstance<KLAService>(); the constructor expects an object of type ICentralLogic and the injector will provide the configured logic object.

Alternatively, you can manually get the configured object for ICentralLogic with ObjectFactory.Container.GetInstance<ICentralLogic>();.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top