4

我正在根据related question的答案探索Castle Windsor的安装程序功能。我想使用Web.config来指定数据库的名称,我宁愿不在我的代码中明确设置数据库名称。我试图克日什托夫·Koźmic的例子,当我登场的项目我的突破点container.Register被击中,但依赖仍然没有解决:Castle Windsor控制反转(IoC):使用Web.config解决依赖关系

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> 

SqlUsersRepositoryIUsersRepository都在同一个命名空间,但他们在当前被引用的类库中的一部分项目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 
} 

任何帮助?

P.S.

我仍然得到一个例外,即使我用的是硬编码的数据库名称(如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文件来存储温莎城堡的特定部分。

+1

请不要使用桑德斯的书,什么温莎相关的,这是非常受现在已经过时。 – 2011-02-26 22:05:12

+0

@Mauricio,使用Web.config存储存储库类所需的连接字符串和数据库名称**具有**有用!它允许你通过简单地添加/更改Web.config中的连接字符串来交换你的数据库......当然,但不是那样。 – Kiril 2011-02-26 22:14:12

+0

。这是一个过时的机制。 – 2011-02-26 22:46:15

回答

1

您应该能够通过减少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属性相匹配即可。

+0

我会给你一个镜头,谢谢! – Kiril 2011-04-19 12:05:06

+0

我仍然得到一个异常:“SqlUsersRepository正在等待以下键......键(具有特定键的组件) - 没有注册的databaseName”。所以我没有得到的部分是如何确定存储库的注册密钥(以及如何确保它与'id'属性匹配? – Kiril 2011-04-21 00:16:30

+0

我最好的猜测在“(...)等待下面的内容键(...)”的错误是,你忘了在实例化一个'XmlInterpreter'传递到温莎,就像这样:'VAR集装箱=新WindsorContainer(新XmlInterpreter())' – mookid8000 2011-04-26 07:44:18

0

我想出了依赖异常...问题是,我的仓库都在不同的装配,所以我不得不钻机安装位:

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的城堡节得到数据库名称虽然。

1

DependsOn你做的方式=命名为“的databaseName”参数有一个关键的“MyDatabaseName”组件的依赖。

你想要做一个.Parameters(ForKey.Named("databasename").Value(ConfigurationManager.ConnectionStrings["MyDatabasename"].ConnectionString)).LifeStyle.Transient. ...

+0

我想避免特别是在程序命名数据库名称资源库......我可以在这告诉我该数据库名的Web.config“自定义”项。随着CastleWindsor,该自定义项应该是在Web.config的' ...'部分,但它不工作,我想我就必须读它自己,而不依赖于CastleWindsor做到这一点。 – Kiril 2011-04-22 04:11:42

相关问题