使用autofac加载外部dll和有条件地注入多个实现的方法
Ways of loading external dll and injecting conditionally multiple implementations using autofac
我有一个名为 IMyHook 的接口,它在外部项目 (dll) 中有一些实现。我在我的业务逻辑 classes 中使用这个接口,在我的应用程序启动时我使用 Autofac 注入这个接口的外部实现。
我的界面
public interface IMyHook {
public void MyHookMethod();
}
我的业务逻辑class
public class myBusinessLogic{
// implementation injected by autofac
public IMyHook Hook {set;get;}
public void MyBusinessLogicMethod (flag){
if(Hook !=null){
Hook.MyHookMethod();
}
else{
// other code
}
}
}
自动面部属性注入
var hoodAssemblyPath = "C:\hook.dll";
builder.RegisterAssemblyTypes(hoodAssemblyPath).
AsImplementedInterfaces().PropertiesAutowired();
一切正常,但现在的问题是我的外部 dll (hook.dll) 可以有多个 IMyHook 实现。我想使用输入参数标志来决定在我的 MyBusinessLogicMethod 方法中加载哪个实现。例如
如果(标志==1)
然后加载实现 1
否则如果(标志== 2)
然后加载实现 2
等等
我可以使用 Reflections(以及我的外部 classes 中的自定义属性来表示标志的每个值)通过加载程序集然后适当的 class 在其上使用自定义属性来完成此操作。
但我的问题是;
这是使用反射等在每个方法调用上加载外部 dll 的正确方法,还是有其他方法可以做到这一点?使用 autofac 或其他任何东西?
有了这一切,我想让我的应用程序的用户将他们的代码注入到我的应用程序中以获得某些功能。所以外部 dll 或实现基本上将由我的用户编写,然后我的应用程序将加载并执行这些方法。
使用 AsImplementedInterfaces().PropertiesAutowired();
注册所有依赖项可能会非常繁重,您可能会在复杂的场景中遇到问题。此外,您将无法自定义每次注册的注册方式(控制 lifetimescope 等)
我建议注册您的用户必须在这些程序集中编写的模块。然后使用 RegisterAssemblyModules
加载它们。
if (flag ==1) then load implementation 1 else if (flag == 2) then load implememtation 2 etc
您将如何决定使用哪个实现? implementation1 表示实现来自 Hook1.dll ?
一个常用的方法是使用 Named and Keyed Services and/or Component Metadata
如果您不能要求您的用户实现模块,您可以使用类似这样的东西:
builder.RegisterAssemblyTypes(hoodAssemblyPath)
.AsImplementedInterfaces()
.PropertiesAutowired()
.WithMetadata("source", "hook1");
然后
IFoo foo = container.Resolve<IEnumerable<Lazy<IFoo, String>>>()
.First(f => f.Metadata["source"] == "hook1")
.Value
如果您这样做,请考虑使用 typed metadata。
我有一个名为 IMyHook 的接口,它在外部项目 (dll) 中有一些实现。我在我的业务逻辑 classes 中使用这个接口,在我的应用程序启动时我使用 Autofac 注入这个接口的外部实现。
我的界面
public interface IMyHook {
public void MyHookMethod();
}
我的业务逻辑class
public class myBusinessLogic{
// implementation injected by autofac
public IMyHook Hook {set;get;}
public void MyBusinessLogicMethod (flag){
if(Hook !=null){
Hook.MyHookMethod();
}
else{
// other code
}
}
}
自动面部属性注入
var hoodAssemblyPath = "C:\hook.dll";
builder.RegisterAssemblyTypes(hoodAssemblyPath).
AsImplementedInterfaces().PropertiesAutowired();
一切正常,但现在的问题是我的外部 dll (hook.dll) 可以有多个 IMyHook 实现。我想使用输入参数标志来决定在我的 MyBusinessLogicMethod 方法中加载哪个实现。例如
如果(标志==1) 然后加载实现 1 否则如果(标志== 2) 然后加载实现 2 等等
我可以使用 Reflections(以及我的外部 classes 中的自定义属性来表示标志的每个值)通过加载程序集然后适当的 class 在其上使用自定义属性来完成此操作。
但我的问题是; 这是使用反射等在每个方法调用上加载外部 dll 的正确方法,还是有其他方法可以做到这一点?使用 autofac 或其他任何东西?
有了这一切,我想让我的应用程序的用户将他们的代码注入到我的应用程序中以获得某些功能。所以外部 dll 或实现基本上将由我的用户编写,然后我的应用程序将加载并执行这些方法。
使用 AsImplementedInterfaces().PropertiesAutowired();
注册所有依赖项可能会非常繁重,您可能会在复杂的场景中遇到问题。此外,您将无法自定义每次注册的注册方式(控制 lifetimescope 等)
我建议注册您的用户必须在这些程序集中编写的模块。然后使用 RegisterAssemblyModules
加载它们。
if (flag ==1) then load implementation 1 else if (flag == 2) then load implememtation 2 etc
您将如何决定使用哪个实现? implementation1 表示实现来自 Hook1.dll ?
一个常用的方法是使用 Named and Keyed Services and/or Component Metadata
如果您不能要求您的用户实现模块,您可以使用类似这样的东西:
builder.RegisterAssemblyTypes(hoodAssemblyPath)
.AsImplementedInterfaces()
.PropertiesAutowired()
.WithMetadata("source", "hook1");
然后
IFoo foo = container.Resolve<IEnumerable<Lazy<IFoo, String>>>()
.First(f => f.Metadata["source"] == "hook1")
.Value
如果您这样做,请考虑使用 typed metadata。