1

私は次のクラスを持っています:

public interface IRenderer<T> 
{
    string Render(T obj);
}

public class Generic<T> { }

public class SampleGenericRenderer<T> : IRenderer<Generic<T>>
{
    public string Render(Generic<T> obj)
    {
        throw new NotImplementedException();
    }
}

ObjectFactory.GetInstance<IRenderer<Generic<string>>>();でStructureMapを呼び出して受信できるようにしたいと思い ますSampleGenericRenderer<string>

現在、次の登録を使用しており、GetInstanceを呼び出すとこのエラーが発生します。"タイプのオブジェクトをキャストできません:

ConsoleApplication1.SampleGenericRenderer'1 [ConsoleApplication1.Generic'1[System.String]]'を入力して'ConsoleApplication1.IRenderer'1[ConsoleApplication1.Generic'1[System.String]]と入力します。

public class CoreRegistry : Registry
{
    public CoreRegistry()
    {
        Scan(assemblyScanner =>
        {
            assemblyScanner
                .AssemblyContainingType(typeof(IRenderer<>));
            assemblyScanner.AddAllTypesOf(typeof(IRenderer<>));
            assemblyScanner
                .ConnectImplementationsToTypesClosing(
                    typeof(IRenderer<>));
        });
    }
}

SampleGenericRenderer<string>代わりに作成するようにStructureMapを構成する方法はありますSampleGenericRenderer<Generic<string>>か?

更新:依存関係のこのサブセットに対して、自分で型の構築を行うことになりました。コンテキストバインディングとサポートされていない多くの汎用バインディングを組み合わせているため、これが最もクリーンなソリューションであることがわかりました。

4

3 に答える 3

2

ピートが説明したように、StructureMapでこれを行う方法はおそらくありません。他のDIコンテナはより多くの成功をもたらす可能性がありますが、すべてのコンテナがより複雑な一般的なトリックを強力にサポートしているわけではありません。あなたがこれを行うことを可能にすることを私が確かに知っている唯一のものはSimpleInjectorです。Simple Injectorでは、次の構成が必要です。

var container = new Container();

container.Register(typeof(IRenderer<>), typeof(SampleGenericRenderer<>));

// Usage
var renderer = container.GetInstance<IRenderer<Generic<string>>>();

renderer.Render(new Generic<string>());

この方法の詳細については、こちらをご覧ください

于 2012-07-11T14:19:40.750 に答える
1

StructureMapには、このような内部ジェネリックパラメーターを閉じるメカニズムはないと思います。

理想的ではありませんが、独自のタイプを作成してみてIRegistrationConvention、閉じたタイプのタイプに遭遇したGeneric<>場合は、次のようにしてください。

var generic_t = typeof(Generic<>).MakeGenericType(type);
var sample_renderer_t = typeof(SampleGenericRenderer<>).MakeGenericType(type);
var renderer_t = typeof(IRenderer<>).MakeGenericType(generic_t);
graph.AddType(renderer_t, sample_renderer_t);

詳細については、 http://docs.structuremap.net/ScanningAssemblies.htm#section11を参照してください。

于 2012-07-10T21:24:27.990 に答える
1

私にとってこれはうまくいきます:

class Program
{
    static void Main()
    {
        ObjectFactory.Configure(x=>x.AddRegistry<CoreRegistry>());

        var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>)) as IRenderer<Generic<string>>;

        var render = instance.Render(new Generic<string>());

    }
}

これは例外をスローします:

ObjectFactory.GetInstance<IRenderer<Generic<string>>>();

あなたの本当の問題は何ですか?

編集:

Generic<string>状況によっては、これも機能する可能性があります(設計時にわからない場合)。

static void Main()
{
    ObjectFactory.Configure(x => x.AddRegistry<CoreRegistry>());

    var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>));
    var methodInfo = instance.GetType().GetMethod("Render");
    methodInfo.Invoke(instance, new[] { new Generic<string>() });
}
于 2012-07-10T19:37:10.447 に答える