c# - 合成后如何更改 MEF 中的部分合成?

标签 c# .net unity-container mef composition

我已将我的应用程序设置为具有可发现的安全服务 ( ISecurityService ),该服务具有单一方法 IPrincipal GetPrincipal() .实现者可以自由决定如何获得委托(delegate)人(通过域登录、数据库等)。所以我的应用程序有一些部分在启动时根据用户所处的角色来做一些事情,例如,我的界面部分是这样导入的:

[Import]
public ISecurityService SecurityService {
    get; set;
}
[ImportMany]
public IEnumerable<ISectionPanel> ImportedPanels {
    get; set;
}
public ObservableCollection<ISectionPanel> Panels {
    get; set;
}
public void OnImportsSatisfied() {
    Panels.Clear();
    IPrincipal p = Thread.CurrentPrincipal;
    foreach (ISectionPanel sp in ImportedPanels.Where(sp => sp.RequiredRole == null || p.IsInRole(sp.RequiredRole))) {
        Panels.Add(p);
    }
}

不要过分关注实现,这将在稍后更改为注释,但是,这里让我大吃一惊的重要事情是部件的组合发生在设置安全主体之前。这意味着我现在遇到了猫捉老鼠的情况。

我现在使用 Lazy<T> 解决了这个问题在影响链接发生的导入上,但是如果部件的另一个实现者忘记使用 Lazy<T>它可能会触发链式加载并导致应用程序失败。

其他人用什么来克服这种情况?

以前我有统一,我通过简单地使用 RegisterInstance<T>(T t) 以更手动的方式控制它,我现在尝试使用框架附带的“官方”MEF 编写应用程序,我不再需要担心统一性。

理想情况下,我希望能够做到的是。

  1. 在启动前手动创建零件
  2. 创建一个组合容器,手动添加我的预构建部件(如 RegisterInstance<T>(T t) 统一
  3. 使用文档中显示的常用组合方法查找剩余部分。

最佳答案

您可以分两个阶段初始化您的应用程序:

public static void Main(string[] args)
{
    using (var container = new CompositionContainer(...))
    {
        // phase 1: compose security service and initialize principal
        var securityService = container.GetExportedValue<ISecurityService>();
        securityService.InitializePrincipal();

        // phase 2: compose the rest of the application and start it
        var form = container.GetExportedvalue<MainForm>();
        Application.Run(form);
    }
}

关于c# - 合成后如何更改 MEF 中的部分合成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5647419/

相关文章:

c# - 如何验证 XmlSerializer 的输出?

c# - Xamarin(android)数据库连接错误

c# - 调试IIS随机疯狂内存使用情况

.net - 如何动态加载单独的应用程序设置文件并与当前设置合并?

.net - 这有可能将 "If Then Else"折叠为方法吗?

c# - Automapper 继承的源和目标

dependency-injection - 是否存在初始化通过 DI 容器创建的对象的模式

c# - 使用数据注释的唯一索引

.net - 使用 DI 传递同一接口(interface)的多个实现

c# - 如何在 PRISM 模块中使用 ReactiveUI