C# 从ServiceHost设置变量

C# 从ServiceHost设置变量,c#,wcf,web-services,servicehost,C#,Wcf,Web Services,Servicehost,在我的项目中,我有一个服务类 class KLAService : IKLAService { CentralLogic centralLogic; ..... } 使用该类,我将ServiceHost设置为: centralLogic = new CentralLogic(); ServiceHost host = new ServiceHost(typeof(KLAService)); using (host) { host.Open(); Appl

在我的项目中,我有一个服务类

class KLAService : IKLAService
{
    CentralLogic centralLogic;

    .....
}
使用该类,我将
ServiceHost
设置为:

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();
}
可能已经很清楚了,我创建了
CentralLogic
类的一个实例。这个实例不仅在UI中使用,而且在主机中也用于管理解决方案中的其他内容

我现在遇到的问题是在
KLAService
-类中(或在
主机中)设置
centralLogic
-变量。我不知道怎么做。我已经读过关于插件Ninject以及如何在服务中注入对象的文章,但这是我力所不及的,我忍不住认为有一种简单的方法

我怎样才能最好地实现我的目标


编辑:提出的另一个解决方案是启动ServiceHost,让
CentralLogic
在那里创建,而不是反过来创建。这意味着ServiceHost需要某种构造函数。我不知道什么是最佳实践,也不知道如何实现这一点。非常感谢您的帮助。

最简单的解决方案是为
CentralLogic
类创建一个单例

如果您想进行依赖项注入,我建议您使用nuget轻松地进行设置,我建议您在
KLAService

下面是一个控制台应用程序,演示如何设置它并将一些本地对象注入其他类:

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();
    }
}
class-KLAService:IKLAService
{
//构造函数注入
公共服务(ICentralLogic逻辑)
{
Console.WriteLine(逻辑值);
}
//手动创建实例
内部无效PrintLogicValue()
{
var logic=ObjectFactory.Container.GetInstance();
Console.WriteLine(逻辑值);
}
}
接口IKLAService
{
}
中央逻辑类:ICentralLogic
{
公共int值{get;set;}
公共中心学()
{
数值=12345;
}
}
接口ICentralLogic
{
int值{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
变量逻辑=新的中央逻辑();
初始化(x=>x.Scan(Scan=>Scan.TheCallingAssembly());
Configure(x=>x.For().Use(y=>logic));
var service=ObjectFactory.Container.GetInstance();
service.PrintLogicValue();
Console.ReadKey();
}
}
当代码调用
var service=ObjectFactory.Container.GetInstance()时构造器需要类型为
ICentralLogic
的对象,喷油器将提供配置的
逻辑
对象


或者,您可以使用
ObjectFactory.Container.GetInstance()手动获取
ICentralLogic
的配置对象

我认为您并不真的需要依赖注入。由于
CentralLogic
只有一个实例,因此它实际上是一个单实例。了解单例模式

您可以在
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()
    {
    }
}
不需要将任何内容传递给ServiceHost


这里最重要的是确保CentralLogic实例是线程安全的。

这很有意义。创建
ServiceHost
如何适应这里?最简单的方法是使用
newservicehost(ObjectFactory.Container.GetInstance())
更改
newservicehost(typeof(KLAService))
,好的,让我试试这个。你能解释一下你用这两行
ObjectFactory
做什么吗?然后,声明
var服务
。我可以在
newservicehost…
行中使用
service
,对吗?
ObjectFactory.Initialize
初始化结构映射以扫描调用程序集的类型,即当前正在运行的应用程序。第二行
ObjectFactory.Container.Configure
告诉它,每当您需要一个带有
ObjectFactory.Container.GetInstance
的实例时,您将获得一个配置对象的实例。然后,您的代码将变为:
ServiceHost host=newservicehost(ObjectFactory.Container.GetInstance())单例对于快速解决方案来说是很好的,而且决不是,我在很多项目中都使用过它们。然而,当您必须进行单元测试时,配置所有单例将是一件相当麻烦的事情。如果你打算做单元测试,我真的会敦促你远离单例测试,它们的维护和配置太麻烦了,特别是如果你想编写其他人可以重用的代码的话。可能的重复更像是这样,我不明白为什么每件事都这么困难。在
ServiceHost
中,如何调用构造函数?我在这方面遇到了麻烦。另一方面,我并不真正需要一个声明
m_centralLogic
的构造函数,但可以使用例如
centralLogic.Instance.GetUsers()。让我试试这个。你应该不会对
KLAService
构造函数有问题-毕竟它是默认(无参数)构造函数-WCF将处理它。是的,您可以使用-
CentralLogic.Instance.Methods()
-请确保
CentralLogic
类的所有方法和属性在其实现中都是线程安全的。
class KLAService : IKLAService
{
    CentralLogic m_centralLogic;

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