如何,当它注入到另一个字符串为一个对象的一个​​方法结合? [英] How to bind a string to a method of an object when it is injected into another?

查看:148
本文介绍了如何,当它注入到另一个字符串为一个对象的一个​​方法结合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 NHibernate.Cfg.Configuration 人员。

ConfigurationProvider

 公共类ConfigurationProvider:提供<结构> {
    公共类ConfigurationProvider(字符串的connectionString
        ,大会映射){
        的ConnectionString =的connectionString;
        映射=映射;
    }    保护覆盖配置的CreateInstance(IContext上下文){
        变种C =新配置()配置()。
        c.AddAssembly(映射);
        c.Properties [connection.connection_string] = ConnectionString的;
        返回℃;
    }    私人只读字符串的ConnectionString;
    私人只读大会映射;
}

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

ConfigurationService

 公共类ConfigurationService {
    公共ConfigurationService(ICurrentUser用户){=的currentUser用户; }    公共字符串BuildConnectionString(){
        返回的String.format(DefaultConnectionString
            ,CurrentUser.DatabaseInstanceName
            ,CurrentUser.Login
            ,CurrentUser.Password);
    }    私人只读ICurrentUser的currentUser;
}

这反过来又依赖于的currentUser 模仿。

的currentUser

 公共类的currentUser:ICurrentUser {
    公众的currentUser(字符串dbinstance具备,登录串,串密码){
        DatabaseInstanceName = dbinstance具备;
        登录=登录;
        Passwword =密码;
    }    公共只读字符串DatabaseInstanceName;
    公共只读字符串登录;
    公共只读字符串密码;
}

人工手动注入我的依赖性看起来像:

 字符串dbinstance具备= authenticationDialog.DatabaseInstanceName;
串登录= authenticationDialog.Login;
字符串密码= authenticationDialog.Password;VAR nHibernateConfigurationProvider =
    新ConfigurationProvider(
        新ConfigurationService(
            新的currentUser(dbinstance具备,登录名,密码))。BuildConnectionString()
        ,Assembly.GetExecutingAssembly());

问题是,我不知道如何绑定,使用Ninject,在 ConfigurationService.BuildConnectionString()的方法来解决字符串中作为构造函数的参数的 ConfigurationProvider.ctor()

推进一步,我怎么告诉Ninject实际结合这些类型只有一次的用户进行身份验证?

这里是我迄今为止

  //等待,直到用户继续绑定之前要验证?
绑定&LT;字符串方式&gt;()ToMethod(CTX =&GT; ctx.Request.???.BuildConnectionString()).WhenInjectedInto<ConfigurationProvider>().InSingletonScope();
Bind<Assembly>().ToConstant<Assembly>(Assembly.GetExecutingAssembly().WhenInjectedInto<ConfigurationProvider>();


解决方案

下面是我的你如何能做到这一点建议。

既然你没有事先的数据,只有当你的 ICurrentUser 通过你所需要的凭据和参数创建,这意味着你需要保存吗?成全局可访问的位置,一旦被创建。

如果我们考虑一个web .NET应用程序,这将涉及tipically绑定 ICurrentUser InRequestScope()使用静态参照的HttpContext

由于这是不是你的话,我选择了绑定 ICurrentUser 作为一个独立的,并初始化它传递价值观。当您需要依赖于它的其他类,容器将通过已经初始化实例,因为它是用约束InSingletonScope()

我也试着模仿当前的依赖关系。例如,而不是在的connectionString 传递给 ConfigurationProvider ,我的方式做这件事的将是对申报的直接依​​赖 ConfigurationService ,以获得的信息。

  //做你的东西,收集凭据//用户已认证的初始化ICurrentUser例如单
//你也可以使用一个ICurrentUserFactory或静态成员,这只是一个样本实现
kernel.Get&LT; ICurrentUser&GT;(新ConstructorArgument(dbinstance具备dbinstance具备)
    新ConstructorArgument(登录,登录),
    新ConstructorArgument(密码,密码));//现在可以正常访问您的NHibernate的配置
无功配置= kernel.Get&lt;结构&GT;();

和绑定:

 绑定&lt;结构&GT;()ToProvider&LT; ConfigurationProvider&GT;();
绑定&LT; ConfigurationProvider&GT;()
    .ToMethod(
        CTX =&GT;新ConfigurationProvider(ctx.Kernel.Get&LT; ConfigurationService&GT;()BuildConnectionString()));绑定&所述; ICurrentUser方式&gt;()到&lt;的currentUser方式&gt;()InSingletonScope();

希望这有助于。

I have a NHibernate.Cfg.Configuration provider.

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

Which the connection string comes from the Configurationservice.BuildConnectionString() of my application.

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

That in turn depends on the CurrentUser to impersonate.

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

So manually injecting my dependency would look like:

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());

The problem is that I don't know how to bind, using Ninject, the ConfigurationService.BuildConnectionString() method to resolve the string used as constructor argument in the ConfigurationProvider.ctor().

Pushing it even further, how do I tell Ninject to actually bind these types only once the user is authenticated?

Here's what I have so far

// 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>();

解决方案

Here is my suggestion on how you can achieve this.

Since you don't have the data beforehand and only when your ICurrentUser is created via the credentials and parameters you need, it means that you need to "save it" into a globally accessible location once it has been created.

If we think about a web .NET application, that would tipically involve binding the ICurrentUser with InRequestScope() using a static reference to a HttpContext.

As this is not your case, I've chosen to bind ICurrentUser as a singleton and initialize it passing the values. When you need your other classes that depend on it, the container will pass the already-initialized instance, since it is bound with InSingletonScope().

I've also tried to mimic your current dependencies. For instance, instead of passing in the connectionString to ConfigurationProvider, my way of doing it would be declare a direct dependency on ConfigurationService in order to obtain the information.

// 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>();

And the bindings:

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

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

Hope this helps.

这篇关于如何,当它注入到另一个字符串为一个对象的一个​​方法结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆