Как правильно создать экземпляр EF Object Data Context, используя DI с Castle? - PullRequest
0 голосов
/ 28 февраля 2012

Пока что у меня есть следующий установщик:

/// <summary>
/// Registers all repositories.
/// </summary>
public class RepositoryInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            AllTypes.FromAssemblyContaining<EntityFrameworkLinkRepository>()
                .BasedOn<IRepository>()
                .WithService.Select(ByConvention)
                .Configure(WithDependencies)
                .LifestylePerWebRequest()
            );
    }

    private IEnumerable<Type> ByConvention(Type type, Type[] types)
    {
        if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
        {
            return Enumerable.Empty<Type>();
        }
        return new[] { type.BaseType };
    }

    private void WithDependencies(ComponentRegistration component)
    {
        Type type = component.Implementation;
        string key;
        if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
        {
            key = type.Name;
        }
        else
        {
            key = type.Name.Substring(0, type.Name.Length - type.BaseType.Name.Length);
        }
        component.DependsOn(new
        {
            connectionString = ConnectionString(key)
        });
    }

    private string ConnectionString(string key)
    {
        string connectionString = Config.GetConnectionString(key);
        return connectionString;
    }
}

, который разрешает хранилища.

Теперь хранилище создается следующим образом:

public class EntityFrameworkLinkRepository : LinkRepository
{
    private readonly ObjectDataContext context; // TODO shouldn't this be receiving a lifetimed ODC, instead of just the connString?

    public EntityFrameworkLinkRepository(string connectionString)
    {
        if (connectionString == null)
        {
            throw new ArgumentNullException("connectionString");
        }
        this.context = new ObjectDataContext(connectionString);
    }

// etc...

Мой вопрос здесь заключается в том, как мне разрешить контекст данных объекта, а не просто создать новый (и даже не избавиться от него), как правильно разрешить контекст данных EF через Castle с помощью DI?

Полагаю, я бы хотел, чтобы ODC был общим для всех репозиториев, относящихся к одному и тому же веб-запросу (это было бы наиболее логичным для меня способом, верно?)

Но так как моя реализацияObjectContext относится только к EntityFramework, я как бы потерялся в том, как я должен разрешить это, я должен явно зарегистрировать это с чем-то вроде этого?

container.Register(
    Component
    .For<ObjectDataContext>()
    .DependsOn(new
    {
        connectionString = ConnectionString("EntityFramework")
    })
    .ImplementedBy<ObjectDataContext>()
);

Ответы [ 2 ]

4 голосов
/ 28 февраля 2012

Как-то так должно работать:

container.Register(
    .Component.For<ObjectDataContext>()
    .DependsOn(
        Dependency.OnValue(
            "connectionString", ConnectionString("EntityFramework")))
    .LifeStyle.PerWebRequest);
2 голосов
/ 28 февраля 2012

Вы должны принимать параметр конструктора для ObjectDataContext. Если вы используете MVC, вы должны также реализовать WindsorControllerFactory, чтобы все ваши контроллеры создавались Windsor и все зависимости конструктора создавались для вас. Вам не нужно создавать и создавать экземпляры чего-либо «сервисного» * ​​1001 *

То, как вы регистрируете свой ObjectDataContext, действительно зависит от того, для какого интерфейса / класса вы написали вещи, которые зависят от него. Итак, если вы написали свой код для самого ObjectDataContext, то приведенный вами пример подойдет. Но если бы вы написали в интерфейс, понадобилось бы что-то подобное ...

container.Register(
    Component
        .For<IObjectDataContext>()
        .ImplementedBy<ObjectDataContext>()
        .DependsOn(new { connectionString = ConnectionString("EntityFramework") })
        .LifeStyle.PerWebRequest
);
...