在我的Windows服务应用程序中,我需要在服务启动时使用配置解析组件。我使用Castle Windsor作为我的IoC容器。
应用程序如下:
public class RootComponent : IRootComponent {
public RootComponent (IDataProvider1 provider1, IDataProvider2 provider2)
{
this.provider1 = provider1;
this.provider2 = provider2;
}
...
}
public class DataProvider1 : IDataProvider1
{
...
public DataProvider1 (IDbHelper dbHelper)
{
this.dbHelper = dbHelper;
}
...
}
public class DataProvider2 : IDataProvider2
{
...
public DataProvider1 (IDbHelper dbHelper)
{
this.dbHelper = dbHelper;
}
...
}
public interface IDbHelper
{
IDbConnection GetNewConnection();
DbParameter CreateDbParameter(string paramName, object paramValue);
string GetCommandString(string commandName);
}
public class MsSqlDbHelper : IDbHelper
{
...
public MsSqlDbHelper(string connectionString)
{
this.connectionString = connectionString;
}
...
}
public class PostgreDbHelper : IDbHelper
{
...
public PostgreDbHelper(string connectionString)
{
this.connectionString = connectionString;
}
...
}
我想在服务构造函数中注册依赖项,在OnStart方法中读取配置并根据它解析正确的IDbHelper:
public partial class MyWindowsService : ServiceBase
{
public MyWindowsService()
{
InitializeComponent();
this.container = new WindsorContainer();
RegisterDependencies();
}
private void RegisterDependencies()
{
container.Register(
Classes.FromAssemblyInThisApplication().BasedOn<IRootComponent>().WithServiceFromInterface(),
Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider1>().WithServiceFromInterface(),
Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider2>().WithServiceFromInterface(),
Classes.FromAssemblyInThisApplication().BasedOn<IDbHelper>().WithServiceFromInterface()
.ConfigureFor<MsSqlDbHelper>(
registration => {
registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString1")));
registration.Named("msSql");
})
.ConfigureFor<PostgreDbHelper>(
registration => {
registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString2")));
registration.Named("postgreSql");
}));
}
protected override void OnStart(string[] args)
{
ResolveDependencies();
}
private void ResolveDependencies()
{
// Helper properties contain "msSql" or "postgreSql" value
root = container.Resolve<IRootComponent>(Config.Provider1Helper, Config.Provider2Helper);
}
...
}
我看到了如何解析配置的IDbHepler的三个选项:
最好的方法是什么?为什么?
答案 0 :(得分:0)
解决方案比我预期的简单。 DynamicParameters就是我所需要的:
private void RegisterDependencies()
{
container.Register(
Classes.FromAssemblyInThisApplication().BasedOn<IRootComponent>().WithServiceFromInterface(),
Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider1>().WithServiceFromInterface()
.Configure(registration => registration.DynamicParameters((kernel, parameters) =>
{
IDbHelper dbHelper = kernel.Resolve<IDbHelper>(Config.Provider1Helper);
parameters.Add("dbHelper", dbHelper);
return k => k.ReleaseComponent(dbHelper);
})),
Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider2>().WithServiceFromInterface(),
.Configure(registration => registration.DynamicParameters((kernel, parameters) =>
{
IDbHelper dbHelper = kernel.Resolve<IDbHelper>(Config.Provider2Helper);
parameters.Add("dbHelper", dbHelper);
return k => k.ReleaseComponent(dbHelper);
})),
Classes.FromAssemblyInThisApplication().BasedOn<IDbHelper>().WithServiceFromInterface()
.ConfigureFor<MsSqlDbHelper>(
registration => {
registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString1")));
registration.Named("msSql");
})
.ConfigureFor<PostgreDbHelper>(
registration => {
registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString2")));
registration.Named("postgreSql");
}));
}
protected override void OnStart(string[] args)
{
// Helper properties should contain "msSql" or "postgreSql" value
// take configuration from arguments
Config.Provider1Helper = UseMsSql(args, 0) ? "msSql" : "postgreSql";
Config.Provider2Helper = UseMsSql(args, 1) ? "msSql" : "postgreSql";
ResolveDependencies();
}
private void ResolveDependencies()
{
root = container.Resolve<IRootComponent>();
}
private bool UseMsSql(string[] args, int argNumber)
{
...
}