【问题标题】:Converting Autofac to Simple Injector将 Autofac 转换为 Simple Injector
【发布时间】:2013-04-16 14:59:54
【问题描述】:

在 Autofac 中我可以执行以下操作

builder
.RegisterType<Services.GreetService>()
    .As<ServiceBase>()
.InstancePerLifetimeScope();

GreetService 继承自 ServiceBase 的地方

我想用 Simple Injector 做同样的事情。

有人知道吗?

谢谢

更新 1

我发现这篇文章他们在 Windows 服务中使用 autofac:http://www.turbulentintellect.com/2011/02/anatomy-of-windows-service-part-2.html

我一直在尝试用 Simple Injector 替换 Autofac,但我无法安装生成的服务。我收到的错误是 System.ArgumentException: Must specify value for source。这通常表示 ServiceInstaller 和 Service 中的 ServiceName 不匹配。

除以下内容外,一切都按照文章设置:

internal class ServiceBootstrapper
{
    //public IContainer Build()
    //{
    //    var builder = new ContainerBuilder();

    //    builder
    //        .RegisterType<GreetService>()
    //        .As<ServiceBase>()
    //        .InstancePerLifetimeScope();

    //    builder
    //        .RegisterType<ServiceNameProvider>()
    //        .As<IServiceNameProvider>()
    //        .InstancePerLifetimeScope();

    //    builder
    //        .RegisterType<Greeter>()
    //        .As<IGreeter>()
    //        .InstancePerLifetimeScope();

    //    return builder.Build();
    //}

    public Container Build()
    {
        var container = new Container();
        
        container.RegisterLifetimeScope<ServiceBase, GreetService>();
        container.RegisterLifetimeScope<IServiceNameProvider, ServiceNameProvider>();
        container.RegisterLifetimeScope<IGreeter, Greeter>();

        container.Verify();

        return container;
    }
}

internal class InstallBootstrapper
{
    //public IContainer Build()
    //{
    //    var builder = new ContainerBuilder();

    //    builder
    //        .RegisterType<HelloServiceProcessInstaller>()
    //        .As<Installer>()
    //        .InstancePerLifetimeScope();

    //    builder
    //        .RegisterType<GreetServiceInstaller>()
    //        .As<Installer>()
    //        .InstancePerLifetimeScope();

    //    builder
    //        .RegisterType<Config.ServiceNameProvider>()
    //        .As<Config.IServiceNameProvider>()
    //        .InstancePerLifetimeScope();

    //    return builder.Build();
    //}

    public Container Build()
    {
        var container = new Container();

        container.RegisterLifetimeScope<HelloServiceProcessInstaller>();
        container.RegisterLifetimeScope<GreetServiceInstaller>();
        container.RegisterLifetimeScope<IServiceNameProvider, ServiceNameProvider>();

        container.Verify();

        return container;
    }
}

public static class Program
{
        public static void Main(String[] args)
        {
            var iocBootstrap = new ServiceBootstrapper();
            var container = iocBootstrap.Build();

            var services = container.GetInstance<ServiceBase>();

            ServiceBase.Run(services);

            //var services = container.Resolve<IEnumerable<ServiceBase>>();

            //ServiceBase.Run(services.ToArray());
        }
}

[RunInstaller(true)]
public class ProjectInstaller : Installer
{
    public ProjectInstaller()
    {
        var bootstrapper = new InstallBootstrapper();
        var container = bootstrapper.Build();

       var processInstallers = container.GetInstance<ServiceProcessInstaller>();
       var serviceInstaller = container.GetInstance<ServiceInstaller>();

        //var installers = container.GetInstance<IEnumerable<Installer>>();
    //var installers = container.Resolve<IEnumerable<Installer>>();

   //Installers.AddRange(installers.ToArray());
       Installers.Add(processInstallers);
       Installers.Add(serviceInstaller); 
    }
}

我肯定在这里遗漏了一些东西,但似乎无法弄清楚。

更新 2

当我使用 InstallUtil 安装服务时,我在安装日志中收到以下信息

运行事务安装。

开始安装的安装阶段。看内容 C:\Local 的日志文件 Development\HelloSvc\HelloSvc\bin\Debug\HelloSvc.exe 程序集的 进步。该文件位于 C:\Local Development\HelloSvc\HelloSvc\bin\Debug\HelloSvc.InstallLog.

安装阶段发生异常。 System.ArgumentException: 必须为源指定值。

安装的回滚阶段即将开始。查看内容 C:\Local 的日志文件 Development\HelloSvc\HelloSvc\bin\Debug\HelloSvc.exe 程序集的 进步。该文件位于 C:\Local Development\HelloSvc\HelloSvc\bin\Debug\HelloSvc.InstallLog.

回滚阶段成功完成。

事务安装已完成。

如前所述,这通常是因为 ServiceName 设置不正确,但我不明白在这种情况下这是怎么可能的。

谢谢

【问题讨论】:

  • 你有没有尝试过?转换有什么问题?你试过container.Register&lt;ServiceBase, GreetService&gt;()吗?或者如果你想要fancy lifetimescoping container.Register&lt;ServiceBase, GreetService&gt;(new LifetimeScopeLifestyle());
  • 关于您的更新:您必须比“想要实现与该文章中的相同”更具体。我试图阅读那篇文章,但仍然不清楚你的问题是什么。如果您无法弄清楚抛出异常的原因,请提供异常详细信息。
  • 另请注意,Simple Injector 明确区分了正常注册和集合注册。对于注册/解析集合,您需要使用RegisterAll&lt;T&gt;/GetAllInstances&lt;T&gt;RegisterAll&lt;T&gt;/GetInstance&lt;IEnumerable&lt;T&gt;&gt;

标签: c# autofac simple-injector


【解决方案1】:

您还没有描述转换有什么问题,所以我尝试回答两个可能的问题/问题:

使用 Register 方法的 Simple Injector 也支持为其基类注册类:

var container = new Container();
container.Register<ServiceBase, GreetService>();

如果您对InstancePerLifetimeScope 部分有疑问,那么您可以在Lifetime Scoping Extensions 中找到类似的LifetimeScopeLifestyle,您可以将其用于:

var container = new Container();
container.Register<ServiceBase, GreetService>(
    new LifetimeScopeLifestyle());

或可选地使用同一包中的RegisterLifetimeScope 扩展方法:

var container = new Container();
container.RegisterLifetimeScope<ServiceBase, GreetService>();

关于你的服务安装问题:

InstallBootstrapper 中,您需要将HelloServiceProcessInstaller 注册为ServiceProcessInstaller,将GreetServiceInstaller 注册为ServiceInstaller,因为稍后您尝试将它们解析为ServiceProcessInstallerServiceInstaller

internal class InstallBootstrapper
{
    public Container Build()
    {
        var container = new Container();

        container.RegisterLifetimeScope<ServiceProcessInstaller, 
                                        HelloServiceProcessInstaller>();
        container.RegisterLifetimeScope<ServiceInstaller, 
                                        GreetServiceInstaller>();
        container.RegisterLifetimeScope<IServiceNameProvider, 
                                        ServiceNameProvider>();

        container.Verify();

        return container;
    }
}

而在ProjectInstaller 中,由于RegisterLifetimeScope,您需要使用`BeginLifetimeScope:

创建一个LifetimeScope
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
    public ProjectInstaller()
    {

        var bootstrapper = new InstallBootstrapper();
        var container = bootstrapper.Build();

        using(container.BeginLifetimeScope())
        {
            var processInstallers = 
                  container.GetInstance<ServiceProcessInstaller>();
            var serviceInstaller = 
                  container.GetInstance<ServiceInstaller>();
            Installers.Add(processInstallers);
            Installers.Add(serviceInstaller);
        }
    }
}

为什么你在安装程序中根本不需要LifetimeScope,所以你可以写:

internal class InstallBootstrapper
{
    public Container Build()
    {
        var container = new Container();

        container.Register<ServiceProcessInstaller, 
                                        HelloServiceProcessInstaller>();
        container.Register<ServiceInstaller, 
                                        GreetServiceInstaller>();
        container.Register<IServiceNameProvider, 
                                        ServiceNameProvider>();

        container.Verify();

        return container;
    }
}

[RunInstaller(true)]
public class ProjectInstaller : Installer
{
    public ProjectInstaller()
    {

        var bootstrapper = new InstallBootstrapper();
        var container = bootstrapper.Build();

        var processInstallers = 
                  container.GetInstance<ServiceProcessInstaller>();
        var serviceInstaller = 
                  container.GetInstance<ServiceInstaller>();
        Installers.Add(processInstallers);
        Installers.Add(serviceInstaller);           
    }
}

【讨论】:

  • 谢谢,不知道我是怎么错过的。我已经更新了我的问题。如果你有机会你介意看看
  • 非常好,问题已经解决。不知道如何使用 Installer 基类注册两个依赖项并解决它们。 Steven 用 RegisterAll 暗示了这一点,但必须发挥作用。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多