我已将我的应用设置为具有可发现的安全服务(ISecurityService
),该服务具有单个方法IPrincipal GetPrincipal()
。实施者可以自由决定如何获得委托人(通过域名登录,数据库等)。所以我的应用程序然后有部分在启动时根据用户所处的角色做事情,例如我导入的界面部分如下:
[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);
}
}
不要过于专注于实现,这将在以后改为注释,然而,这使得我作为一个gutser的重要事情是部件的组成发生在安全主体设置之前。这意味着我现在有猫捉老鼠的情况。
我现在通过在导入时使用Lazy<T>
来解决这个问题,这会影响链接,但是如果某个部分的另一个实现者忘记使用Lazy<T>
,它可能会触发链式加载并导致应用失败。
其他人用什么来克服这种情况?
之前我通过简单地使用RegisterInstance<T>(T t)
以更加手动的方式控制了团结,我现在尝试使用“官方”MEF编写应用程序,因为这带有框架,我不再需要担心团结。
理想情况下,我希望能够做到的是。
RegisterInstance<T>(T t)
in unity 答案 0 :(得分:4)
您可以分两个阶段初始化您的应用程序:
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);
}
}
答案 1 :(得分:2)
在MEF中,与RegisterInstance
或多或少相对应的是AddExportedValue
方法。如果主机在不使用MEF的情况下创建安全服务,这将起作用。由于您仍然希望通过MEF发现安全服务,Wim建议的可能是一个很好的解决方案。