3

このドキュメントに従って、型付きファクトリを使用し、コンストラクターにパラメーターを渡します。コードに示されているように、2つのパラメーター(1、 "fo")を渡そうとすると、型指定されたファクトリからこのエラーが発生します。

ここに画像の説明を入力してください

public class SomeClass {
    public ITypedFactory2 F2 { get; set; } 
    public void SomeFunction() {
        var req = F2.Create<IGetFooRequest>(1, "fo"); // ERROR HERE
    }
}
public class GetFooRequest : IGetFooRequest {
    public int Bar { get; private set; }
    public string Ton { get; private set; }
    public GetFooRequest(int bar, string ton ) {
        Bar = bar;
        Ton = ton;
    }
}
public interface IGetFooRequest{
    int Bar { get; }
    string Ton { get; }
}    
public interface ITypedFactory2 {
    T Create<T>(int param1, string param2);
    void Release(object t);
}

これはウィンザーインストーラーの部分です...

container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactory2>().AsFactory());
container.Register(AllTypes
            .FromAssemblyContaining<IGetFooRequest>()
            .Where(type => type.Name.EndsWith("Request"))
            .WithService.AllInterfaces().LifestyleTransient());

オプションではない依存関係を解決できなかったと表示されるのはなぜですか...?(1、 "fo");を渡しました。なぜこれが起こっているのか本当にわかりません...助けてください。

4

3 に答える 3

8

私は同じ質問をして、答えを見つけました。ファクトリメソッドのパラメータ名とクラスコンストラクタのパラメータ名は、大文字と小文字を区別せずに一致する必要があります。

したがって、ファクトリインターフェイスをに変更します

public interface ITypedFactory2 {
    T Create<T>(int **bar**, string **ton**);
    void Release(object t);
}

またはあなたのクラスに

public class GetFooRequest : IGetFooRequest {
    public int Bar { get; private set; }
    public string Ton { get; private set; }
    public GetFooRequest(int **param1**, string **param2**) {
        Bar = bar;
        Ton = ton;
    }
}
于 2013-07-24T21:51:39.370 に答える
2

私は自分のコードを見て、(int param1、string param2)はよく見えないと言いました。(int bar、string ton)を使用させてください...そしてその命名で問題が修正されました。LoL信じられない、そして私はその文書が命名の重要性について言及しているのを見ません。

幸いなことに、ここでのイントロでは、依存関係は最初に名前で解決され、次にタイプで解決されると述べていることを覚えています。これが名前の部分がその仕事をしていて、タイプの部分が水に入ったということです。とにかく、使い方がわかって良かったので、ここで必要な人と答えを共有します。

于 2012-07-29T07:01:45.520 に答える
1

パラメータ名をタイプで解決したい場合は、独自の名前を作成できますComponentSelector

public class ComponentSelector : DefaultTypedFactoryComponentSelector
{
    protected override Arguments GetArguments(MethodInfo method, object[] arguments)
    {
        if (arguments == null)
            return null;

        Arguments argumentMap = new Arguments();
        ParameterInfo[] parameters = method.GetParameters();

        List<Type> types = parameters.Select(p => p.ParameterType).ToList();
        List<Type> duplicateTypes = types.Where(t => types.Count(type => type == t) > 1).ToList();

        for (int i = 0; i < parameters.Length; i++)
        {
            if (duplicateTypes.Contains(parameters[i].ParameterType))
                argumentMap.Add(parameters[i].Name, arguments[i]);
            else
                argumentMap.Add(parameters[i].ParameterType, arguments[i]);
        }

        return argumentMap;
    }
}

私の実装でわかるように、コンストラクターに同じタイプの複数のパラメーターがある場合を処理する必要があります。
その場合Castle.Windsor、同じタイプを持つすべてのパラメーターに対してタイプの最初のパラメーターを使用するため、パラメーター名で解決する必要があります。

自分で使用するには、自分ComponentSelectorにも登録する必要がありますIWindsorContainer

container.Register(Component.For<ComponentSelector, ITypedFactoryComponentSelector>());

ComponentSelector最後に、コンポーネントセレクターとして独自のものを使用するようにファクトリに指示する必要があります。

container.Register(Component.For<ITypedFactory2>().AsFactory(f => f.SelectedWith<ComponentSelector>()));

詳細については、カスタムコンポーネントセレクターの使用方法に関する公式ドキュメントを確認してください。

于 2019-04-10T15:30:27.413 に答える