0

私の同僚は、私たちのプロジェクトで Windsor TypedFactoryFacility をセットアップしました。

私は Windsor を初めて使用し、ファクトリとして登録する IServiceFactory インターフェイスのメソッドを実装する方法を理解していません。型パラメーター T を受け取り、T を返す Create メソッドを見たとき、おそらく内部でコンテナーの Resolve メソッドを呼び出しているのではないかと考えました。

Type をパラメーターとして取り、オブジェクトを返す Create のオーバーロードが必要です。コンテナーの Resolve メソッドには、次の両方のフレーバーがあるため:

T Resolve<T>(string key);
object Resolve(Type service);

Create のオーバーロードを追加するとうまくいくと思いました。代わりに、渡された Type I ではなく System.Object を解決しようとしているようです。

Windsor で Create メソッドを希望どおりに実装する方法はありますか? リフレクターでちょっと調べてみましたが、よくわかりません。

登録は次のとおりです。

container.AddFacility<TypedFactoryFacility>();
        container.Register(
                Component.For<IServiceFactory>()
                        .AsFactory()
                        .LifeStyle.Transient);

およびインターフェース自体:

public interface IServiceFactory
{
    //Original Create method that works
    T Create<T>();

    //The overload that I need that throws an exception
    object Create(Type service)

    void Release(object service);
}
4

1 に答える 1

0

serviceFactory.Create(typeof(IMyServce))の代わりに次のようなものを呼び出しますserviceFactory.Create<IMyService>()か?

このように、拡張メソッドでリフレクションを使用してみてください

public static class ServiceFactoryExtensions
{
    public static object Create(this IServiceFactory factory, Type serviceType)
    {
        return typeof(IServiceFactory).GetMethod("Create")
            .MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
    }
}

編集:

この拡張メソッドは、Castle Windsor によって作成されたファクトリで実際に機能します。

これが私の元のテスト コードです。これを VS2010 コンソール アプリケーションの Program.cs にドロップし、Castle.Core と Castle.Windsor への参照を追加して実行できます。Castle.Windsor 2.5.4を使用しました。

using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace StackOverflow9198461
{
    public static class ServiceFactoryExtensions
    {
        public static object Create(this IServiceFactory factory, Type serviceType)
        {
            return typeof(IServiceFactory).GetMethod("Create")
                .MakeGenericMethod(serviceType)
                .Invoke(factory, new object[] { });
        }
    }

    class Program
    {
        static void Main()
        {
            var container = new WindsorContainer();
            container.AddFacility<TypedFactoryFacility>();
            container.Register(Component
                .For<IServiceFactory>()
                .AsFactory());
            container.Register(Component
                .For<IMyService>()
                .ImplementedBy<MyService>()
                .LifeStyle.Singleton);
            var factory = container.Resolve<IServiceFactory>();
            var s1 = factory.Create<IMyService>();
            var s2 = factory.Create(typeof(IMyService));
            Console.WriteLine(s1.GetType().FullName);
            Console.WriteLine(s2.GetType().FullName);
            if (s1 == s2) Console.WriteLine("Success");
        }
    }

    public interface IServiceFactory
    {
        //Original Create method that works
        T Create<T>();

        ////The overload that I need that throws an exception
        //object Create(Type service)

        void Release(object service);
    }

    public class MyService : IMyService
    {
    }

    public interface IMyService
    {
    }
}
于 2012-02-23T10:30:48.283 に答える