创建ContainerBuilder的新实例是一种好习惯吗?

以下示例代码基本上调用了多个虚拟服务,并将结果组合在一起。(在实际应用中,它们将是Web服务。)

问题:创建ContainerBuilder的新实例是一种好习惯吗?请在Main方法中看到几个*****。

如果没有,您能指出我正确的方向吗?我愿意接受任何建议。

注意: Build()或Update()方法只能在ContainerBuilder上调用一次。

输出

在此处输入图片说明

主要的

private static void Main(string[] args)
{
    var builder = new ContainerBuilder();
    var container = builder.Build();

    // ***** Create a new instance of ContainerBuilder *****
    builder = new ContainerBuilder(); 
    builder.RegisterType<AlfaService>().As<IService>().Named<IService>("a");
    builder.RegisterType<BravoService>().As<IService>().Named<IService>("b");
    builder.Update(container);

    // ***** Create a new instance of ContainerBuilder *****
    builder = new ContainerBuilder(); 
    var services = new Dictionary<string, IService>
    {
        {"a", container.ResolveNamed<IService>("a")},
        {"b", container.ResolveNamed<IService>("b")}
    };
    builder.RegisterType<CompositeService>().As<ICompositeService>()
        .WithParameter("services", services);
    builder.Update(container);


    // The following is for testing purpose only.
    // In real application, I'll inject ICompositeService to MVC controller.
    using (ILifetimeScope scope = container.BeginLifetimeScope())
    {
        IList<int> ids = scope.Resolve<ICompositeService>().GetIdsBySource("a");
        Console.WriteLine("AlfaService: " + string.Join(", ", ids));

        ids = scope.Resolve<ICompositeService>().GetAllIds();
        Console.WriteLine("All Services: " + string.Join(", ", ids));
    }
    Console.ReadLine();
}

介面

public interface ICompositeService
{
    IList<int> GetIdsBySource(string source);

    IList<int> GetAllIds();
}

public interface IService
{
    IList<int> GetIds();
}

服务

public class CompositeService : ICompositeService
{
    private readonly Dictionary<string, IService> _services;

    public CompositeService(Dictionary<string, IService> services)
    {
        _services = services;
    }

    public IList<int> GetIdsBySource(string source)
    {
        return _services.Where(x => x.Key == source)
            .Select(x => x.Value).First().GetIds();
    }

    public IList<int> GetAllIds()
    {
        return _services.SelectMany(x => x.Value.GetIds()).ToList();
    }
}

public class AlfaService : IService
{
    public IList<int> GetIds() { return new List<int> {1, 2, 3}; }
}

public class BravoService : IService
{
    public IList<int> GetIds() { return new List<int> {4, 5, 6}; }
}
西里尔·杜兰德

要解析参数中的某些内容,无需构建容器。建造一个集装箱要花费一些时间,如果可能的话应该避免。

解决参数内部问题的最简单方法是使用如下WithParameter方法:

builder.RegisterType<CompositeService>()
        .As<ICompositeService>()
        .WithParameter((pi, c) => pi.Name == "services", (pi, c) =>
        {
            return new Dictionary<string, IService> {
                { "a", c.ResolveNamed<IService>("a") }, 
                { "b", c.ResolveNamed<IService>("b") } 
            };
        });

另一个解决方案是创建自己的 Parameter

public class ServiceParameter : Parameter
{
    public override Boolean CanSupplyValue(ParameterInfo pi,
        IComponentContext context, out Func<Object> valueProvider)
    {
        valueProvider = null;
        if (pi.Name == "services" 
            && pi.ParameterType == typeof(Dictionary<String, IService>))
        {
            valueProvider = () =>
            {
                return new Dictionary<string, IService> {
                    { "a", context.ResolveNamed<IService>("a") }, 
                    { "b", context.ResolveNamed<IService>("b") } 
                };
            };
        }
        return valueProvider != null;
    }
}

并以这种方式注册:

builder.RegisterType<CompositeService>()
        .As<ICompositeService>()
        .WithParameter(new ServiceParameter());

就您而言,您可能要使用元数据来代替命名服务

builder.RegisterType<AlfaService>().As<IService>().WithMetadata("Key", "a");
builder.RegisterType<BravoService>().As<IService>().WithMetadata("Key", "b");

在CompositeService中,您将依赖 IEnumerable<Meta<IService>>

public CompositeService(IEnumerable<Meta<IService>> services)
{
    _services = services.ToDictionary(m => (String)m.Metadata["Key"], m => m.Value);
}

如果您不想引入Meta对您的依赖关系,则CompositeService可以使用自定义方式Parameter,将您IEnumerable<Meta<IService>>IDictionary<String, IService>

public class ServiceParameter : Parameter
{
    public override Boolean CanSupplyValue(ParameterInfo pi,
        IComponentContext context, out Func<Object> valueProvider)
    {
        valueProvider = null;
        if (pi.Name == "services" 
            && pi.ParameterType == typeof(Dictionary<String, IService>))
        {
            valueProvider = () =>
            {
                IEnumerable<Meta<IService>> services = 
                    context.Resolve<IEnumerable<Meta<IService>>>(); 
                return services.ToDictionary(m => (String)m.Metadata["Key"], 
                                             m => m.Value);
            };
        }
        return valueProvider != null;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

创建这样的Java Frame是一种好习惯吗?

来自分类Dev

在C#中缓存异常实例是一种好习惯吗

来自分类Dev

指向类的C ++指针,调用释放类实例的函数,这是一种好习惯吗?

来自分类Dev

将已经实例化的属性传递给using语句是一种好习惯吗?

来自分类Dev

创建并使用String对象锁定线程同步是一种好习惯吗?

来自分类Dev

在python中创建嵌套类是一种好习惯吗?

来自分类Dev

为特定设置创建类是一种好习惯吗?

来自分类Dev

Rails,创建没有视图的方法是一种好习惯吗?

来自分类Dev

通过联接表创建SQL视图是一种好习惯吗?

来自分类Dev

在React组件中创建状态而不更改状态是一种好习惯吗?

来自分类Dev

创建对调用方法返回的值的未使用引用是一种好习惯吗?

来自分类Dev

在Eclipse中为每个类创建单独的Java文件是一种好习惯吗?

来自分类Dev

假冒插入程序是一种好习惯吗?

来自分类Dev

扩展课堂是一种好习惯吗?

来自分类Dev

在ThreadPoolExecutor中设置allowCoreThreadTimeOut()是一种好习惯吗?

来自分类Dev

使用WCF简化配置是一种好习惯吗?

来自分类Dev

经常使用instanceof是一种好习惯吗?

来自分类Dev

编写接口以帮助测试是一种好习惯吗?

来自分类Dev

在$ rootScope中存储变量是一种好习惯吗?

来自分类Dev

索引数组字面量是一种好习惯吗?

来自分类Dev

嵌套诺言是一种好习惯吗?

来自分类Dev

大量使用本地存储是一种好习惯吗?

来自分类Dev

打破特殊事件的for循环是一种好习惯吗?

来自分类Dev

在ReactJS中操作DOM是一种好习惯吗?

来自分类Dev

静态导入是一种好习惯吗?

来自分类Dev

从ViewModel调用业务逻辑是一种好习惯吗

来自分类Dev

便利功能是一种好习惯吗?

来自分类Dev

设置包装器类是一种好习惯吗?

来自分类Dev

编写接口以帮助测试是一种好习惯吗?

Related 相关文章

  1. 1

    创建这样的Java Frame是一种好习惯吗?

  2. 2

    在C#中缓存异常实例是一种好习惯吗

  3. 3

    指向类的C ++指针,调用释放类实例的函数,这是一种好习惯吗?

  4. 4

    将已经实例化的属性传递给using语句是一种好习惯吗?

  5. 5

    创建并使用String对象锁定线程同步是一种好习惯吗?

  6. 6

    在python中创建嵌套类是一种好习惯吗?

  7. 7

    为特定设置创建类是一种好习惯吗?

  8. 8

    Rails,创建没有视图的方法是一种好习惯吗?

  9. 9

    通过联接表创建SQL视图是一种好习惯吗?

  10. 10

    在React组件中创建状态而不更改状态是一种好习惯吗?

  11. 11

    创建对调用方法返回的值的未使用引用是一种好习惯吗?

  12. 12

    在Eclipse中为每个类创建单独的Java文件是一种好习惯吗?

  13. 13

    假冒插入程序是一种好习惯吗?

  14. 14

    扩展课堂是一种好习惯吗?

  15. 15

    在ThreadPoolExecutor中设置allowCoreThreadTimeOut()是一种好习惯吗?

  16. 16

    使用WCF简化配置是一种好习惯吗?

  17. 17

    经常使用instanceof是一种好习惯吗?

  18. 18

    编写接口以帮助测试是一种好习惯吗?

  19. 19

    在$ rootScope中存储变量是一种好习惯吗?

  20. 20

    索引数组字面量是一种好习惯吗?

  21. 21

    嵌套诺言是一种好习惯吗?

  22. 22

    大量使用本地存储是一种好习惯吗?

  23. 23

    打破特殊事件的for循环是一种好习惯吗?

  24. 24

    在ReactJS中操作DOM是一种好习惯吗?

  25. 25

    静态导入是一种好习惯吗?

  26. 26

    从ViewModel调用业务逻辑是一种好习惯吗

  27. 27

    便利功能是一种好习惯吗?

  28. 28

    设置包装器类是一种好习惯吗?

  29. 29

    编写接口以帮助测试是一种好习惯吗?

热门标签

归档