Caching 如何使用decorator模式(Castle Windsor)在typedfactory上正确设置缓存?

Caching 如何使用decorator模式(Castle Windsor)在typedfactory上正确设置缓存?,caching,castle-windsor,decorator,typed-factory-facility,Caching,Castle Windsor,Decorator,Typed Factory Facility,我正在使用Castle Windsor,我正在尝试使用decorator模式在TypedFactory上设置缓存。在我尝试处理Windsor容器(关闭应用程序时)之前,它工作正常。基本上,我的问题是当我试图处理CachedFactory时,TypedFactory已经被处理了 以下是我的问题的简化示例: using System; using System.Collections.Generic; using System.Threading; using Castle.Facilities.T

我正在使用Castle Windsor,我正在尝试使用decorator模式在TypedFactory上设置缓存。在我尝试处理Windsor容器(关闭应用程序时)之前,它工作正常。基本上,我的问题是当我试图处理CachedFactory时,TypedFactory已经被处理了

以下是我的问题的简化示例:

using System;
using System.Collections.Generic;
using System.Threading;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            // Setting up the container
            var container = new WindsorContainer();
            container.AddFacility<TypedFactoryFacility>();
            container.Register(
                Component.For<IItemFactory>().ImplementedBy<CachedItemFactory>(), //decorator pattern
                Component.For<IItemFactory>().AsFactory(),
                Component.For<IItem>().ImplementedBy<Item>().LifestyleTransient()
                );

            // Resolving
            var itemFactory = container.Resolve<IItemFactory>();

            // Desired behavior. Works as expected.
            IItem item1 = itemFactory.Create("Item1");
            IItem item2 = itemFactory.Create("Item2");
            IItem anotherItem1 = itemFactory.Create("Item1");
            Console.WriteLine("Item1 == Item2: {0}", item1 == item2); //false
            Console.WriteLine("Item1 == anotherItem1: {0}", item1 == anotherItem1); //true

            // Here is my problem. It throws ObjectDisposedException from _itemFactory in the Dispose function of CachedItemFactory
            container.Dispose();

            Console.WriteLine("End of program");
            Console.ReadKey();
        }
    }

    public interface IItem
    {
        string Name { get; }
    }

    public class Item : IItem
    {
        public Item(string name)
        {
            Name = name;
            Thread.Sleep(1000); //It takes time to create this object
        }

        public string Name { get; private set; }
    }

    public interface IItemFactory
    {
        IItem Create(string name);
        void Release(IItem item);
    }

    public class CachedItemFactory : IItemFactory, IDisposable
    {
        private readonly Dictionary<string, IItem> _cache = new Dictionary<string, IItem>();
        private readonly IItemFactory _itemFactory;

        public CachedItemFactory(IItemFactory itemFactory)
        {
            _itemFactory = itemFactory;
        }

        public IItem Create(string name)
        {
            if (!_cache.ContainsKey(name))
                _cache.Add(name, _itemFactory.Create(name));
            return _cache[name];
        }

        public void Release(IItem item)
        {
        }

        public void Dispose()
        {
            foreach (var item in _cache)
            {
                _itemFactory.Release(item.Value);
            }
            _cache.Clear();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用Castle.Facilities.TypedFactory;
使用Castle.MicroKernel.Registration;
使用温莎城堡;
命名空间控制台应用程序1
{
内部课程计划
{
私有静态void Main(字符串[]args)
{
//设置容器
var container=新的WindsorContainer();
container.AddFacility();
集装箱。登记(
Component.For().ImplementedBy(),//装饰器模式
Component.For().AsFactory(),
Component.For().ImplementedBy().LifestyleTransient()实现
);
//解决
var itemFactory=container.Resolve();
//期望的行为。按预期工作。
IItem item1=itemFactory.Create(“item1”);
IItem item2=itemFactory.Create(“item2”);
IItem anotherItem1=itemFactory.Create(“Item1”);
WriteLine(“Item1==Item2:{0}”,Item1==Item2);//false
WriteLine(“Item1==anotherItem1:{0}”,Item1==anotherItem1);//true
//这是我的问题。它在CachedItemFactory的Dispose函数中从_itemFactory抛出ObjectDisposedException
container.Dispose();
控制台写入线(“程序结束”);
Console.ReadKey();
}
}
公共接口项
{
字符串名称{get;}
}
公共类项目:IItem
{
公共项(字符串名称)
{
名称=名称;
Thread.Sleep(1000);//创建此对象需要时间
}
公共字符串名称{get;private set;}
}
公共接口项目工厂
{
IItem创建(字符串名称);
无效释放(项目项);
}
公共类CachedItemFactory:IItemFactory,IDisposable
{
专用只读词典_cache=new Dictionary();
私有只读IItemFactory _itemFactory;
公共CachedItemFactory(IItemFactory itemFactory)
{
_itemFactory=itemFactory;
}
公共项目创建(字符串名称)
{
if(!\u cache.ContainsKey(名称))
_cache.Add(名称,_itemFactory.Create(名称));
返回_缓存[名称];
}
公共无效释放(项目项)
{
}
公共空间处置()
{
foreach(缓存中的变量项)
{
_itemFactory.Release(item.Value);
}
_cache.Clear();
}
}
}
你知道我做错了什么吗?有任何概念(架构)错误吗

我尝试了以下方法,但没有成功:

  • 在CachedItemFactory之前注册TypedFactory(并将CachedItemFactory标记为IsDefault):不工作,相同错误
  • 手工实现基本工厂而不是使用TypedFactory:同样的问题
  • 这起到了作用:

  • 手动实现一个基本工厂,在CachedItemFactory之前注册它,并将CachedItemFactory标记为IsDefault。。。但感觉不对(脆弱)
  • 有什么评论吗


    非常感谢

    您正在将缓存和typedfactory都注册为单例(隐式)。 如果将TypeFactory注册为Transient,它可能(不完全确定)会在缓存工厂之后立即被释放


    但是,由于您仅尝试清理工厂的已解析组件,您也可以省略Dispose中的代码,因为类型化工厂在发布时将释放其所有组件。

    使用CASTLE WINDSOR AOP添加业务层缓存