3

我的应用程序需要能够存储来自登录模块的连接字符串,以供应用程序中的所有其他模块使用,其中大约有 50 个。我最初打算通过广播和订阅新的/更改的连接字符串事件来使连接字符串可用,但是由于 50 个模块中的大多数/全部是按需加载的,因此它们在登录过程中无法订阅该事件,因为它们是登录过程后加载。根据我的理解,我需要一种不同的方法来使连接字符串可用。

然后我考虑将连接字符串放在 shell 中并尝试将其公开给任何加载的模块,但我找不到一种方法来做到这一点,而不会破坏 MVVM 模式并引入不需要的依赖项。

如果有人知道实现上述两个选项中的任何一个的方法,我会很想知道它是否可以在遵循 MVVM 模式的同时完成。

我现在在想,最好的方法是对连接字符串使用单例的一些变体作为共享服务。我希望 Unity Container 能够存储连接字符串,并且我可以使用服务定位器在任何模块中访问它,但我不知道该怎么做。MEF 和/或 Silverlight 中有任何性质相似的示例。 有没有人在 WPF 中这样做过,或者有一个如何编写连接字符串单例并将其添加到 Unity 容器的示例?指南、教程或一些代码片段将不胜感激!

注意:我在后端使用 Prism 和 Unity、Oracle,应用程序将部署在 Citrix 服务器上(以安全的名义,他们阻止开发人员写入 app.config),这就是为什么我不能使用这种方法. 当多个用户从 Citrix 运行应用程序时,使用 Singleton 作为连接字符串也会导致问题吗?每个用户都有自己的单例连接字符串吗? 如果不是,那么我的整个问题都会改变,是否有一种好方法可以用来传递/保留所有模块之间的连接字符串?

4

2 回答 2

0

如果您使用的是 Prism,我强烈建议 Unity Container 注册连接字符串并将 ctor-dependency 注入到您拥有的各种 VM 中。

有点像,定义其他程序集/虚拟机可以使用它的合同,以及 LoginModule 中的实现:

class ConnectionInfo : IConnectionInfo 
{
    public GetConnectionString()
    {
      // you get the drift...!  
      // you should probably cache the result into a Lazy<T> impl. and just return
      // that value on future calls, to save the lookup of the config.
    }
}

在登录模块中注册它:

container.RegisterType<IConnectionInfo, ConnectionInfo>(
  new ContainerControlledLifetimeManager());

并且在你的虚拟机的ctor中进行DI它 - 在这一点上它是无忧无虑的:

public MyViewModel(IConnectionInfo connectionInfo_)
{
  var connectionString = connectionInfo_.GetConnectionString();
}

我想我对这些情况的首选方法是更喜欢 IEventAggregator 之上的接口,如果我可以选择的话。它只是更容易处理诸如由于事件信号发生得太早而导致迟创建的 VM 没有接收 IEA 信号的情况。这将导致一些真正痛苦的技术债务积累。

于 2013-04-10T23:22:07.943 回答
0

要回答有关如何在 Unity 容器中注册连接字符串的问题,您应该能够使用以下代码段实现所需的结果。

存储连接字符串:

Container.RegisterInstance<string>("ConnectionString", theConnectionString);

检索连接字符串:

var connectionString = Container.Resolve<string>("ConnectionString");

正如我在上面的评论中提到的,另一种选择可能是创建一个请求和一个响应类型,您可以使用 EventAggregator 来回发送,让每个模块请求连接字符串并让登录模块回复。

var MyToken = Guid.NewGuid();

EventAggregator.GetEvent<ConnectionStringResponse>().Subscribe(r => {
    if(r.Token != MyToken)  // Make sure we're only handling responses to our request.
        return;

    ConnectionString = r.ConnectionString;
    // Kick off whatever other stuff you need to do once
    // you've gotten the connection string
    // Might also want to unsubscribe at this point unless you want
    // to go even further and handle changing connection strings.
});

EventAggregator.GetEvent<ConnectionStringRequest>().Publish(MyToken);
于 2013-04-10T23:03:16.243 回答