Castle Windsor 解析 ienumerable 和 name

Castle Windsor resolve ienumerable and name

我是 Castle Windsor(实际上是 DI)的新手,正在尝试使用 windsor 解决一个场景,但我有点卡住了。为了给出一个想法,有 2 个不同的远程源,我需要在第一次尝试时从那里获取给定客户的一些订单信息,这有点耗时。订单信息将来永远不会改变,因此我想将该数据存储在我的本地数据库中以供后续使用,这将提高我的应用程序的性能。

装饰器模式似乎是一个很好的选择,下面是我的初步尝试。

public interface IOrderRepository
{
    IEnumerable<OrderInfo> Get(string customerNo);
    void Save(string customerNo, IEnumerable<OrderInfo> orders);
}

public class RealTimeRepo1 : IOrderRepository
{
     public IEnumerable<OrderInfo> Get(string customerNo)
     {
       /// Fetch the data from remote source 1
     }
     public void Save(string customerNo, IEnumerable<OrderInfo> orders)
     {
         /// You cannot update the order info in remote source
         throw new NotImplementedException();
     }
 }

public class RealTimeRepo2 : IOrderRepository
{
     public IEnumerable<OrderInfo> Get(string customerNo)
     {
       /// Fetch the data from remote source 2
     }
     public void Save(string customerNo, IEnumerable<OrderInfo> orders)
     {
         /// You cannot update the order info in remote source
         throw new NotImplementedException();
     }
 }

 public LocalOrderRepo : IOrderRepository
 {
     public IEnumerable<OrderInfo> Get(string customerNo)
     {
       /// Fetch the data from local data source

     }
     public void Save(string customerNo, IEnumerable<OrderInfo> orders)
     {
         /// Save the data on local data source
     }
 }

 public CacheOrderRepo : IOrderRepository
 {
     private readonly IEnumerable<IOrderRepository> realTimeRepos;
     private readonly IOrderRepository localRepo;

     public CacheOrderRepo(IEnumerable<IOrderRepository> realTime, IOrderRepository localRepo)
     {
           this.realTimeRepos = realTime;
           this.localRepo = localRepo;
     }

     public IEnumerable<OrderInfo> Get(string customerNo)
     {
         List<OrderInfo> orders = this.localRepo.Get(customerNo);
         if(orders == null) && (!orders.Any()
         {
             foreach(var r in this.realTimeRepos)
             {
                List<OrderInfo> t = r.Get(customerNo);
                if(t.Any())
                {
                  orders.AddRange(t);
                }
             }
             if(orders.Any())
             {
                 this.localRepo.save(customerNo, orders);
             }
         }
         return orders;
     }
     public void Save(string customerNo, IEnumerable<OrderInfo> orders)
     {
         /// Save the data on local data source
     }
 }

我希望上面的代码片段能提供一个思路。我的难题是如何使用 windsor 注册它。

//regsiter
this._container.Kernal.Resolver.AddSubResolver(new  
    CollectionResolver(this._container.Kenrnal));

this._container.Register(
    Component.For<IOrderRepository>.ImplementedBy<RealTimeRepo1>().LifeStyle.Transient,
    Component.For<IOrderRepository>.ImplementedBy<RealTimeRepo2>().LifeStyle.Transient
 );

使用集合子解析器,我能够注册一个 ienumerable 的实时回购 1 和 2。我应该如何注册本地回购(即我的构造函数参数 2)?

感谢您的帮助。我也愿意根据我对装饰器模式或温莎城堡的理解提出建议...

首先您需要注册CollectionResolver

其次,我建议您将 CacheOrderRepo 的构造函数更改为显式引用 LocalOrderRepo 或为其定义不同的抽象(例如 ILocalOrderRepo)。

public class CacheOrderRepo : IOrderRepository
{
    private readonly IEnumerable<IOrderRepository> realTimeRepos;
    private readonly LocalOrderRepo localRepo;

    public CacheOrderRepo(IEnumerable<IOrderRepository> realTime, LocalOrderRepo localRepo)
    {
        this.realTimeRepos = realTime;
        this.localRepo = localRepo;
    }

然后通过先注册compositeCacheOrderRepo)来完成注册,像这样:

var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(
    Component.For<IOrderRepository>().ImplementedBy<CacheOrderRepo>(),
    Component.For<IOrderRepository>().ImplementedBy<RealTimeRepo1>(),
    Component.For<IOrderRepository>().ImplementedBy<RealTimeRepo2>(),
    Component.For<LocalOrderRepo>().ImplementedBy<LocalOrderRepo>());

var service = container.Resolve<IOrderRepository>();
Assert.IsInstanceOf<CacheOrderRepo>(service);