Loading dependencies in Unity Container in WinForms application
这就是部分解决方案的样子。
由于我在 Winforms 环境中使用 Onion 架构,因此我拥有 UI、基础设施和核心层。所有层都使用依赖注入松散耦合。我想要实现的是,每当一个表格来自例如帐户表单(类库)已加载,所有依赖项都应加载到 UnityContainer 中,即已注册的类型。这些依赖项是核心和基础架构项目中存在的接口和实现。
我的困惑是我应该在哪里编写代码来注册依赖项?这个应用程序的组合根是什么?请注意,来自例如的表格Accounts Forms、HR Forms 等都是使用 Main Windows 应用程序中的反射加载的,该应用程序仅引用 Base Forms Project。
根据 Eben Roux 的建议
这是我在加载程序集时执行连线代码的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Dim assemb As System.Reflection.Assembly ... ... If assemb IsNot Nothing Then Dim type As Type = GetType(IDependencyWiring) Dim modules As List(Of Type) = assemb.GetTypes().Where(Function(p) type.IsAssignableFrom(p) AndAlso p.IsClass).ToList() For Each [module] As Type In modules Dim argTypes As Type() = New Type() {} Dim cInfo As ConstructorInfo = [module].GetConstructor(argTypes) Dim dependencyWiringModule As IDependencyWiring = DirectCast(cInfo.Invoke(Nothing), IDependencyWiring) dependencyWiringModule.WireUp() Next End If |
这里是具有 WireUp 方法的模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Public Class AccountModule : Implements IDependencyWiring Private Shared Container As IUnityContainer Public Sub New() Container = New UnityContainer() End Sub Public Sub WireUp() Implements IDependencyWiring.WireUp Container.RegisterType(Of IInterface1, Class1)() Container.RegisterType(Of IInterface2, Class2)() Container.RegisterType(Of IInterface3, Class3)() Container.RegisterType(Of IInterface4, Class4)() End Sub Public Shared Function Resolve(typeToResolve As Type) As Object Return Container.Resolve(typeToResolve.GetType())() End Function End Class |
所以我现在的问题是:
使用这种类型的插件架构,您实际上会得到多个组合根(各种)。很可能会有一些依赖关系,只有您的插件知道并且可以连接。
因此,您的架构的一部分应该是插件的加载。这可能发生在主应用程序的连线位(组合根)中的某个位置,这将使每个插件都有机会执行其连线。
由于并非所有插件都需要接线,因此可以通过使用单独的接口来明确说明:
1 2 3 4 | public interface IDependencyWiring { public void WireUp(IDependencyContainer container); // <-- changed to conform to update } |
然后在主成分根中:
1 2 3 4 5 6 7 8 9 | foreach (var plugin in plugins) { var wiring = plugin as IDependencyWiring; if (wiring != null) { wiring.WireUp(myContainer); } } |
我希望这是有道理的。
更新:
首先我会使用安全演员表。
1 2 3 4 5 6 7 | public interface IDependencyContainer { void Register(Type type); void Register< T >(); void Resolve(Type type); void Resolve< T >(); } |
好吧,你会添加你需要的东西。然后像我在顶部
上所做的那样,在连线中传递对容器的引用