Как заставить StructureMap автоматически регистрировать базовые интерфейсы? - PullRequest
1 голос
/ 17 ноября 2011

Наши репозитории на работе, как правило, CRUD, разбитые на одно из ICreatable, IRetrievable, IUpdatable и IDeletable. Поведение извлечения использует PK объекта в своем извлечении. Зачастую мы получим еще один подчиненный интерфейс для обработки методов вне поведения CRUD для хранилища. Это выглядит так:

public interface IUserRepository : ICreatable<User>, IRetrievable<User>, IUpdatable<User>
{
    IEnumerable<User> GetUsersWithoutEmail ();
}

public class UserRepository : IUserRepository
{
    // implement members...
}

В местах, где нам конкретно нужно GetUsersWithoutEmail, мы добавим IUserRepository. Где-то еще, которому нужно IRetrievable<User>, в настоящее время получается IUserRepository, потому что я не знаю, как решить эту проблему.

То, что я хотел бы сделать, это что-то похожее на это:

ObjectFactory.Initialize (x => x.For<IUserRepository> ().IncludeBaseInterfaces ().Use <UserRepository> ());

Я хочу получить UserRepository, когда я запрашиваю IUserRepository или IRetrievable<User>, без необходимости конфигурировать каждый из 4 вручную. Я хотел бы иметь возможность переопределить один, если я решу, что ICreatable<User> должен быть CreatableUserRepository вместо этого, но обычно я просто хочу, чтобы он поднимался по дереву как можно дальше.

Это выполнимо?

1 Ответ

2 голосов
/ 01 декабря 2011

Я думаю, что вам в конечном итоге понадобится какой-то сумасшедший логический объект, который поможет вам справиться с подобными вещами на верхнем уровне StructureMap - я не знаю ни одной функциональности, которая дает вам такую ​​условную обработку.

Итак, вы бы смотрели что-то вроде:

public class NestedInheritanceConvention : IRegistrationConvention
{
    public void Process (Type type, Registry registry)
    {
        if (type.IsInterface)   
            return;

        if (type.IsAbstract)    
            return;

        if (type.IsSubclassOf (typeof(Registry)))
            return;

        foreach (var iface in type.GetInterfaces ())
        {
            registry.For (iface).Use (type);
        }
    }
}

Что бы ваш вызов StructureMap выглядел примерно так:

    public StructureMapRegistry ()
    {
        Scan (x => 
        {
            x.Convention<NestedInheritanceConvention> ();
        });
    }
...