Castle Windsor Inversion of Control (IoC): Using Web.config to resolve dependencies

I studied Castle Windsor installer functionality based on the answers of the question . I want to use Web.config to specify the database name, and I would prefer not to explicitly specify the database name in my code. I tried the Krzysztof KoΕΊmic example, and when I debut in the project, my break point in container.Register hits, but the dependency is still not resolved:

 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 suggests that we can use Web.config to resolve dependencies (note that he does this to get the connection string, but my connection string is encrypted, so I do it a little differently):

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

My SqlUsersRepository and IUsersRepository are in the same namespace , but they are part of the class library referenced in the current project . SqlUsersRepository looks at the connection string from the Web.Config database name:

 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 } 

Any help on this?

PS

I still get the exception, even if I use a hard-coded database name (as shown in RepositoriesInstaller ):

Server error in application "/". cannot create component 'MyProjectName.Controllers.UserController' because it has dependencies on satisfied. MyProjectName.Controllers.UserController waits for the following Dependencies:

Services: - MyProjectName.Entities.IUsersRepository which has not been registered. Description: An unhandled exception occurred during the execution of the current network request. View the stack trace for more information about the error and where it originated in the code.

Exception Details: Castle.MicroKernel.Handlers.HandlerException: Unable to create component 'MyProjectName.Controllers.UserController' because it has dependencies on satisfied. MyProjectName.Controllers.UserController waits for the following Dependencies:

Services: - MyProjectName.Entities.IUsersRepository which has not been registered.

Update I posted an answer regarding the exception problem, but I still didn't understand how to use Web.config to store individual sections of Castle Windsor.

+4
source share
3 answers

You should be able to achieve this by reducing the XML to this:

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

and then make sure that your registration registers the repository with the correct key / id - for example. eg:

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

where all keys will be set to the short name of each particular type.

Please note that this naming scheme may not be appropriate for you, so you should probably adapt c.Named(...) to whatever you think is right for your use case. Just make sure the registration key for your repository matches this id attribute in XML.

+1
source

DependsOn how you did it = a parameter named "database_name" has a component dependency with the key "MyDatabaseName".

You want to do .Parameters(ForKey.Named("databasename").Value(ConfigurationManager.ConnectionStrings["MyDatabasename"].ConnectionString)).LifeStyle.Transient. ... .Parameters(ForKey.Named("databasename").Value(ConfigurationManager.ConnectionStrings["MyDatabasename"].ConnectionString)).LifeStyle.Transient. ...

+1
source

I found out the dependency exception ... the problem was that my repositories are in a different assembly, so I had to install the installation a bit:

 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" }))); } } 

Still trying to figure out how to get the database name from the Web.config lock section, though.

0
source

Source: https://habr.com/ru/post/1341467/


All Articles