ric*_*rdo 3 generics dependency-injection autofac
我觉得我对使用AutoFac可以做些什么感到困惑,有人可以让我走上正轨.
我有一个基本类型
class PersonBase{
public string SaySomething(){
return "I am base";
}
}
Run Code Online (Sandbox Code Playgroud)
我推导出两个具体的课程
class FakePerson : PersonBase{
public override string SaySomething(){
return "I'm so Fake";
}
}
class RealPerson : PersonBase{
public override string SaySomething(){
return "I am For Real";
}
}
Run Code Online (Sandbox Code Playgroud)
创建一个泛型类PersonHandler,以处理不同类型的人,并希望PersonHandler在适当的时候实例化该人,所以我不想要一个Person实例注入,只需要派生类型
class PersonHandler<T>
where T : PersonBase, new() {
T _Person;
public DoWork(){
_Person = new T();
_Person.SaySomething();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我尝试使用处理程序,在注册下面详细说明的类型后,会有不同的结果.
var ph = contrainer.Resolve<PersonHandler<PersonBase>>();
ph.DoWork();
Run Code Online (Sandbox Code Playgroud)
我试图按如下方式注册类型
1. vBuilder.RegisterType<PersonHandler<FakePerson>>().As<PersonHandler<PersonBase>>();
Run Code Online (Sandbox Code Playgroud)
这给了我一个错误,说明PersonHandler<FakePerson>不能分配PersonHandler<PersonBase>(或者反过来我不会重新分配哪个)
2. vBuilder.RegisterGeneric<typeof(PersonHandler<>)>
vBuilder.RegisterType<FakePerson>().As<PersonBase>();
Run Code Online (Sandbox Code Playgroud)
这不能解决PersonBase来FakePerson,但只是给PersonHandler<PersonBase>,所以它导致"我基地"
3. vBuilder.RegisterGeneric(typeof(PersonHandler<FakePerson>)).As(typeof(PersonHandler<PersonBase>));
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误,说这PersonHandler<FakePerson>不是一个开放类型
所以现在我整天都在追逐自己的故事,坦率地说,它正在逐渐退出繁琐,
请帮忙
Nic*_*rdt 10
(差不多)正确的解决方案是您已尝试过的解决方案:
builder.RegisterType<PersonHandler<FakePerson>>()
.As<PersonHandler<PersonBase>>();
Run Code Online (Sandbox Code Playgroud)
Autofac给你一个错误的原因是C#中的泛型类不能以这种方式工作.
也就是说,你不能写:
PersonHandler<PersonBase> ph = new PersonHandler<FakePerson>();
Run Code Online (Sandbox Code Playgroud)
(在IDE中试一试 - 编译器会拒绝它.)
这样做的原因是,C#4中添加的必需功能的逆转仅支持接口类型.
简而言之,如果您创建IPersonHandler<T>并使用它作为服务,那么上面的代码将按预期工作:
interface IPersonHandler<in T>
where T : PersonBase, new() {
void DoWork();
}
Run Code Online (Sandbox Code Playgroud)
请注意in接口声明中的参数.
制作PersonHandler<T>工具IPersonHandler<T>:
class PersonHandler<T> : IPersonHandler<T>
where T : PersonBase, new() {
Run Code Online (Sandbox Code Playgroud)
然后像这样注册:
builder.RegisterType<PersonHandler<FakePerson>>()
.As<IPersonHandler<PersonBase>>();
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下方式获取处理
IPersonHandler<PersonBase> handler =
container.Resolve<IPersonHandler<PersonBase>>();
Run Code Online (Sandbox Code Playgroud)
返回的handler对象将是类型PersonHandler<FakePerson>.
| 归档时间: |
|
| 查看次数: |
4775 次 |
| 最近记录: |