Castle Windsor Inversion of Control (IoC): использование Web.config для разрешения зависимостей - PullRequest
4 голосов
/ 26 февраля 2011

Я изучал функциональность установщика Castle Windsor на основе ответов на вопрос . Я хочу использовать Web.config для указания имени базы данных, и я бы не стал явно указывать имя базы данных в своем коде. Я попробовал пример Krzysztof Koźmic, и когда я дебютирую в проекте, моя точка останова на container.Register получает удар, но зависимость все еще не разрешена:

public class RepositoriesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(AllTypes.FromThisAssembly()
                            .Where(Component.IsInSameNamespaceAs<SqlUsersRepository>())
                            .WithService.DefaultInterface()
                            .Configure(c => c.LifeStyle.Transient
                            .DependsOn(new { databaseName = "MyDatabaseName" })));
    }
}

Сандерс предполагает, что мы можем использовать Web.config для разрешения зависимостей (обратите внимание, что он делает это, чтобы получить строку подключения, но моя строка подключения зашифрована, поэтому я делаю это немного по-другому):

<castle>
    <components>
      <component id="SqlUsersRepository"
          service="MyDevArmyModel.Entities.IUsersRepository, MyDevArmyModel"
          type="MyDevArmyModel.Entities.SqlUsersRepository, MyDevArmyModel">
        <parameters>
          <databaseName>MyDatabaseName</databaseName>
        </parameters>
      </component>
    </components>
</castle>

Мои SqlUsersRepository и IUsersRepository находятся в одном и том же пространстве имен, , но они являются частью библиотеки классов, на которую есть ссылки в текущем проекте . SqlUsersRepository ищет строку подключения из Web.Config имени базы данных:

public interface IUsersRepository
{
    IQueryable<User> Users { get; }
    // ...
    // and some other things 
    // ...

}

public class SqlUsersRepository : IUsersRepository
{
    private DataContext dataContext;
    private Table<User> usersTable;

    public IQueryable<User> Users { get { return usersTable; } }

    public SqlUsersRepository(string databaseName)
    {
        HttpRequestWrapper request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);
        Configuration config = WebConfigurationManager.OpenWebConfiguration(request.ApplicationPath);
        dataContext = new DataContext(config.GetConnetionString(databaseName));
        usersTable = dataContext.GetTable<User>();
    }

    // .... the rest of the repository goes here
}

Есть какая-нибудь помощь по этому поводу?

приписка

Я все еще получаю исключение, даже если я использую жестко закодированное имя базы данных (как показано в RepositoriesInstaller):

Ошибка сервера в «/» приложении. не может создать компонент 'MyProjectName.Controllers.UserController' поскольку у него есть зависимости, чтобы быть довольный. MyProjectName.Controllers.UserController ждет следующего Зависимости:

Услуги: - MyProjectName.Entities.IUsersRepository который не был зарегистрирован. Описание: Необработанное исключение произошло во время выполнение текущей сети запрос. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и откуда оно взято в коде.

Сведения об исключении: Castle.MicroKernel.Handlers.HandlerException: Не могу создать компонент 'MyProjectName.Controllers.UserController' поскольку у него есть зависимости, чтобы быть довольный. MyProjectName.Controllers.UserController ждет следующего Зависимости:

Услуги: - MyProjectName.Entities.IUsersRepository который не был зарегистрирован.

Обновление Я опубликовал ответ, который решает проблему исключений, но мне еще предстоит выяснить, как использовать Web.config для хранения определенных разделов Castle Windsor.

Ответы [ 3 ]

1 голос
/ 19 апреля 2011

Вы должны быть в состоянии достичь этого, сократив XML до этого:

<castle>
    <components>
      <component id="SqlUsersRepository">
        <parameters>
          <databaseName>MyDatabaseName</databaseName>
        </parameters>
      </component>
    </components>
</castle>

и затем убедитесь, что ваша регистрация регистрирует репозиторий под правильным ключом / идентификатором - например, как это:

container.Register(AllTypes(...).Configure(c => c.Named(c.Implementation.Name)))

, где для всех ключей будет задано короткое имя каждого конкретного типа.

Обратите внимание, что эта схема именования может не подходить для вас, поэтому вам, вероятно, следует адаптировать c.Named(...) к тому, что вы считаете правильным для вашего варианта использования. Просто убедитесь, что регистрационный ключ для вашего хранилища совпадает с этим, если атрибут id в XML.

1 голос
/ 22 апреля 2011

DependsOn как вы это сделали = параметр с именем «databaseName» имеет зависимость компонента с ключом «MyDatabaseName».

Вы хотите сделать .Parameters(ForKey.Named("databasename").Value(ConfigurationManager.ConnectionStrings["MyDatabasename"].ConnectionString)).LifeStyle.Transient. ...

0 голосов
/ 27 февраля 2011

Я выяснил исключение зависимости ... проблема заключалась в том, что мои репозитории находятся в другой сборке, поэтому мне пришлось немного смонтировать установку:

public class RepositoriesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        foreach (AssemblyName name in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
        {
            Assembly asm = Assembly.Load(name);
            container.Register(AllTypes.FromAssemblyNamed(asm.FullName)
                            .Where(Component.IsInSameNamespaceAs<SqlUsersRepository>())
                            .WithService.DefaultInterface()
                            .Configure(c => c.LifeStyle.Transient
                            .DependsOn(new { databaseName = "MyDatabaseName" })));
        }

        container.Register(AllTypes.FromThisAssembly()
                            .Where(Component.IsInSameNamespaceAs<SqlUsersRepository>())
                            .WithService.DefaultInterface()
                            .Configure(c => c.LifeStyle.Transient
                            .DependsOn(new { databaseName = "MyDatabaseName" })));
    }
}

Все еще пытаюсь выяснить, как получить имя базы данных из раздела замка Web.config.

...