我已将我的应用程序设置为具有可发现的安全服务 ( 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 编写应用程序,我不再需要担心统一性。
理想情况下,我希望能够做到的是。
- 在启动前手动创建零件
- 创建一个组合容器,手动添加我的预构建部件(如
RegisterInstance<T>(T t)
统一 - 使用文档中显示的常用组合方法查找剩余部分。
最佳答案
您可以分两个阶段初始化您的应用程序:
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/