c# – Castle Windsor控制反转(IoC):使用Web.config解决依赖关系

我正在根据
related question的答案探索Castle Windsor的安装程序功能.我想使用Web.config来指定数据库的名称,我宁愿不在我的代码中显式设置数据库名称.我尝试了KrzysztofKoź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" })));
    }
}

Sanders建议我们可以使用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中所示),我仍然会遇到异常:

Server Error in ‘/’ Application. Can’t
create component
‘MyProjectName.Controllers.UserController’
as it has dependencies to be
satisfied.
MyProjectName.Controllers.UserController
is waiting for the following
dependencies:

Services:
– MyProjectName.Entities.IUsersRepository
which was not registered. Description:
An unhandled exception occurred during
the execution of the current web
request. Please review the stack trace
for more information about the error
and where it originated in the code.

Exception Details:
Castle.MicroKernel.Handlers.HandlerException:
Can’t create component
‘MyProjectName.Controllers.UserController’
as it has dependencies to be
satisfied.
MyProjectName.Controllers.UserController
is waiting for the following
dependencies:

Services:
– MyProjectName.Entities.IUsersRepository
which was not registered.

更新
我发布了一个解决异常问题的答案,但我还没弄清楚如何使用Web.config存储Castle Windsor特定部分.

最佳答案 您应该能够通过将XML减少到此来实现此目的:

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

然后确保您的注册在正确的密钥/ id下注册存储库 – 例如像这样:

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

其中所有键都将设置为每种具体类型的短名称.

请注意,此命名方案可能不适合您,因此您应该将c.Named(…)调整为您认为适合您的用例的任何内容.只需确保存储库的注册密钥与XML中的id属性匹配即可.

点赞