Вопрос по generics, c#, structuremap – Регистрация метода на универсальной фабрике с помощью StructureMap

4

Я пытаюсь использовать метод для универсального класса фабрики в моем реестре структуры карты. Обычно при регистрации типа с использованием фабричного метода я бы использовал следующее:

For<Foo>().Use(x => new FooFactory().GetFoo());

И следующее при регистрации универсального типа:

For(typeof(ISomeGeneric<>)).Use(typeof(SomeGeneric<>));

Как я могу объединить два и получить универсальный тип из универсального фабричного метода? Я думаю, что это должно быть что-то вроде:

For(typeof(IFoo<>)).Use(typeof(x => new FooFactory<>().Create(someParameter));

Это просто дает

"Cannot convert lambda expression to type object because it is not a delegate type" 

ошибка. Я пробовал разные комбинации, но тупик. Есть идеи?

Благодарю.

Вы когда-нибудь находили решение для этого? Я изучаю, как сделать нечто подобное. Jeff Treuting

Ваш Ответ

1   ответ
0

НО я бы искал альтернативу, если можно. Проблема заключается в том, что для работы с открытым универсальным форматом необходимо использовать некоторое отражение. Это означает, что вы получите удар по производительности.

public class FooRegistry:Registry
{
    public FooRegistry()
    {
        For(typeof(IFoo<>)).Use(x =>
        {
            var ParamType = x.BuildStack.Current.RequestedType
                             .GetGenericArguments()[0];
            return BuildUsingFooFactory(ParamType);
        });
    }

    private object BuildUsingFooFactory(Type paramType)
    {
        var factoryType = typeof (FooFactory<>).MakeGenericType(new[] {paramType});
        var createMethod = factoryType.GetMethod("Create");
        object factory = Activator.CreateInstance(factoryType);
        return createMethod.Invoke(factory, new[] {"SomeParameterString"});
    }
}

public class FooFactory<T>
{
    public IFoo<T> Create(string param)
    {
        return new Foo<T>();
    }

}

public interface IFoo<T>
{
}

public class Foo<T> : IFoo<T>
{   
}

Что вы делаете по порядку:

Find out what the requested generic argument is. (ParamType) Create a non-open generic type for the factory (factoryType) Grab the create method off of it. (createMethod) Create an instance of the factory using the Activator (factory) Call the create method on the factory instance with your some parameter.

StructureMap заботится о преобразовании вывода в правильный интерфейс.

Better Solution

Вместо непосредственного использования IFoo, используйте IFooFactory. Это делает его намного чище, у вас есть открытое универсальное отображение на IFooFactory & lt; & gt ;. Затем просто получите тип FooFactory, который вам нужен для генерации ваших объектов.

public class FooRegistry:Registry
{
    public FooRegistry()
    {
        For(typeof (IFooFactory<>))
            .Use(typeof (FooFactory<>))
            .CtorDependency<string>("connection")
            .Is("SomeConnectionString");
    }
}


public interface IFooFactory<T>
{
    IFoo<T> CreateInstance();
}

public class FooFactory<T> : IFooFactory<T>
{
    public FooFactory(string connection)
    {
    } 

    public IFoo<T> CreateInstance()
    {
        return new Foo<T>();
    }
}

public interface IFoo<T>
{
}

public class Foo<T> : IFoo<T>
{   
}

Похожие вопросы