我正在构建一个c#Asp.Net应用程序。 我的项目中有三个程序集。
AssemblyA
和AssemblyB
引用了MainAssembly。 MainAssembly将使用Reflection加载AssemblyA
和AssemblyB
。
需要AutoFac来根据它所在的程序集来解析类型。
换句话说,构造函数参数应根据它所属的程序集解析为SmsSender
或EmailSender
。
请考虑以下代码:
-------------------------- MainAssembly内的代码 ----------- ---------------
//Global Registration
void AutofacRegister()
{
var builder = new ContainerBuilder();
...
...
//Registering the modules in other assemblies
builder.RegisterAssemblyModules(AssemblyA);
builder.RegisterAssemblyModules(AssemblyB);
...
}
interface ISender
{
void SendMessage();
}
-------------------------- AssemblyB内的代码 ----------- -----------------
public class ComponentA: Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SmsSender>().As<ISender>();
}
}
internal class SmsSender : ISender{...}
public class Foo()
{
Foo(ISender sender)
{
//as this is inside a AssemblyA thi should be resolved to type SmsSender
//SmsSender
}
}
-------------------------- AssemblyB内的代码 ----------- -----------------
public class ComponentA: Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<EmailSender>().As<ISender>();
}
}
internal class EmailSender : ISender{...}
public class Bar()
{
Bar(ISender sender)
{
//as this is inside a AssemblyB this should be resolved to type EmailSender
//EmailSender
}
}
我如何达到要求? 可以通过提供一个简单的例子来帮助我吗?
答案 0 :(得分:0)
有多种方法可以解决您的问题,但您必须明确“告诉”您Foo
和Bar
他们应该使用的ISender
类。您可以使用“命名实例”来执行此操作。
首先,我假设MainAssembly中不存在ISender
接口,因为如果MainAssembly引用了这两个组件,它在ComponentA和ComponentB中是不可访问的。
您的 ComponentA 模块定义应如下所示:
public class ModuleDefinition : Module
{
protected override void Load(ContainerBuilder builder)
{
const string emailSender = "EmailSender";
builder.RegisterType<EmailSender>().As<ISender>().Named<ISender>(emailSender);
builder.RegisterType<Foo>()
.WithParameter((p, c) => p.Name == "sender", (p, c) => c.ResolveNamed<ISender>(emailSender));
}
}
类似地, ComponentB 模块定义如下所示:
public class ModuleDefinition : Module
{
protected override void Load(ContainerBuilder builder)
{
const string smsSender = "SmsSender";
builder.RegisterType<SmsSender>().As<ISender>().Named<ISender>(smsSender);
builder.RegisterType<Bar>()
.WithParameter((p, c) => p.Name == "sender", (p, c) => c.ResolveNamed<ISender>(smsSender));
}
}
如您所见,我使用ISender
配置方法明确配置Foo
和Bar
类应使用哪个.WithParameter
实现。
AFAIK没有隐含的“基于程序集”的方式。