如何将字符串绑定到另一个对象的方法时将其绑定到对象的方法?

时间:2014-04-10 19:16:00

标签: authentication nhibernate dependency-injection ninject desktop-application

我有一个NHibernate.Cfg.Configuration提供商。

ConfigurationProvider

public class ConfigurationProvider : Provider<Configuration> {
    public class ConfigurationProvider(string connectionString
        , Assembly mappings) {
        ConnectionString = connectionString;
        Mappings = mappings;
    } 

    protected override Configuration CreateInstance(IContext context) {
        var c = new Configuration().Configure();
        c.AddAssembly(Mappings);
        c.Properties["connection.connection_string"] = ConnectionString;
        return c;
    }

    private readonly string ConnectionString;
    private readonly Assembly Mappings;
}

连接字符串来自我的应用程序的Configurationservice.BuildConnectionString()

ConfigurationService

public class ConfigurationService {
    public ConfigurationService(ICurrentUser user) { CurrentUser = user; }

    public string BuildConnectionString() {
        return string.Format(DefaultConnectionString
            , CurrentUser.DatabaseInstanceName
            , CurrentUser.Login
            , CurrentUser.Password);
    }

    private readonly ICurrentUser CurrentUser;
}

反过来又取决于CurrentUser来冒充。

CurrentUser

public class CurrentUser : ICurrentUser {
    public CurrentUser(string dbinstance, string login, string password) { 
        DatabaseInstanceName = dbinstance;
        Login = login;
        Passwword = password;
    }

    public readonly string DatabaseInstanceName;
    public readonly string Login;
    public readonly string Password;
}

因此,手动注入我的依赖关系将如下所示:

string dbInstance = authenticationDialog.DatabaseInstanceName;
string login = authenticationDialog.Login;
string password = authenticationDialog.Password;

var nHibernateConfigurationProvider = 
    new ConfigurationProvider(
        new ConfigurationService(
            new CurrentUser(dbInstance, login, password)).BuildConnectionString()
        , Assembly.GetExecutingAssembly());

问题是我不知道如何使用Ninject绑定ConfigurationService.BuildConnectionString()方法来解析string中用作构造函数参数的ConfigurationProvider.ctor()

进一步推动,如何在用户通过身份验证后告诉Ninject实际绑定这些类型?

这是我到目前为止的内容

// Wait until user is authenticated before continuing to bind???
Bind<string>().ToMethod(ctx => ctx.Request.???.BuildConnectionString()).WhenInjectedInto<ConfigurationProvider>().InSingletonScope();
Bind<Assembly>().ToConstant<Assembly>(Assembly.GetExecutingAssembly().WhenInjectedInto<ConfigurationProvider>();

1 个答案:

答案 0 :(得分:2)

以下是关于如何实现这一目标的建议。

由于您事先没有数据,并且仅当您通过所需的凭据和参数创建ICurrentUser时,这意味着您需要将其“保存”到一个全球可访问的位置创建

如果我们考虑一个Web .NET应用程序,那将使用ICurrentUser的静态引用将InRequestScope()HttpContext绑定在一起。

由于这不是你的情况,我选择将ICurrentUser绑定为单例并初始化它传递值。当您需要依赖它的其他类时,容器将传递已初始化的实例,因为它与InSingletonScope()绑定。

我也试图模仿你当前的依赖关系。例如,我不是将connectionString传递给ConfigurationProvider,而是通过ConfigurationService声明直接依赖于获取信息。

// Do your stuff to collect credentials

// User now authenticated, initialize ICurrentUser instance singleton
// You could have used a ICurrentUserFactory or static member, this is just a sample implementation
kernel.Get<ICurrentUser>(new ConstructorArgument("dbInstance", dbInstance),
    new ConstructorArgument("login", login),
    new ConstructorArgument("password", password));

// You can now access your NHibernate configuration properly
var config = kernel.Get<Configuration>();

绑定:

Bind<Configuration>().ToProvider<ConfigurationProvider>();
Bind<ConfigurationProvider>()
    .ToMethod(
        ctx => new ConfigurationProvider(ctx.Kernel.Get<ConfigurationService>().BuildConnectionString()));

Bind<ICurrentUser>().To<CurrentUser>().InSingletonScope();

希望这有帮助。