0

Castle Windsor を使用しており、デコレータ パターンを使用して 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();
        }
    }
}

私が間違っていることのアイデアはありますか?概念的な (アーキテクチャ上の) エラーはありますか?

次のことを試しましたが、成功しませんでした:

  1. CachedItemFactory の前に TypedFactory を登録する (および CachedItemFactory を IsDefault としてマークする): 機能しない、同じエラー
  2. TypedFactory を使用する代わりに手動で基本的なファクトリを実装する: 同じ問題

これはうまくいきました:

  1. 基本的なファクトリを手動で実装し、それを CachedItemFactory の前に登録し、CachedItemFactory を IsDefault としてマークします...しかし、それは間違っているように感じます (壊れやすい)...

コメントはありますか?

どうもありがとう!

4

1 に答える 1