我似乎无法在Autofac中绕过这种情况:
所以我试图为IFinal创建一个工厂,但我似乎无法使解决方案正确。
示例代码:
public static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Dependency>().As<IDependency>();
builder.RegisterType<Final>().As<IFinal>();
// this fails because context c is not available at the time finalObjectFactoryMethod is used
builder.Register<Factory>((c,p)=>{
var dependency = c.Resolve<IDependency>();
Func<int, IFinal> finalObjectFactoryMethod =
rta => c.Resolve<IFinal>(
new TypedParameter(typeof(IDependency), dependency),
new TypedParameter(typeof(int), rta)
);
return new Factory(finalObjectFactoryMethod);
}).As<IFactory>();
// this works but doesn't use the resolve mechanism for IFinal
/*
builder.Register<Factory>((c,p)=>{
var dependency = c.Resolve<IDependency>();
Func<int, IFinal> finalObjectFactoryMethod = rta => new Final(dependency, rta);
return new Factory(finalObjectFactoryMethod);
}).As<IFactory>();
*/
IContainer container = builder.Build();
IFactory factory = container.Resolve<IFactory>();
IFinal final = factory.GetFinalObject(42);
}
}
public interface IDependency{}
public class Dependency: IDependency{}
public interface IFinal
{
void Test();
}
public class Final: IFinal
{
public Final(IDependency dependency, int runtimeArgument){}
public void Test(){}
}
public interface IFactory
{
IFinal GetFinalObject(int runtimeArgument);
}
public class Factory: IFactory
{
readonly Func<int, IFinal> _finalObjectFactoryMethod;
public Factory(Func<int, IFinal> finalObjectFactoryMethod)
{
_finalObjectFactoryMethod = finalObjectFactoryMethod;
}
public IFinal GetFinalObject(int runtimeArgument)
{
return _finalObjectFactoryMethod(runtimeArgument);
}
}
Google和Autofac文档对此无法帮助我 不知何故,我的大脑似乎有一个结,也许我只是试图使用错误的模式 我很确定有一个解决方案,但我无法找到它。
答案 0 :(得分:1)
很好的例子“问正确的问题,你会找到正确的答案” 我一直试图让这个工作2天,我在这里发布问题后1小时,我自己找到了答案:P
这是包括Interceptor的工作代码:
class MainClass
{
public static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Interceptor>();
builder.RegisterType<Dependency>().As<IDependency>();
builder.RegisterType<Final>().As<IFinal>();
builder.Register<IFinal>((c, p) =>
{
IDependency dependency = c.Resolve<IDependency>();
int runtimeArgument = p.Named<int>("runtimeArgument");
return new Final(dependency, runtimeArgument);
}).As<IFinal>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(Interceptor));
builder.Register<Factory>((c,p)=>{
Factory.FactoryMethod finalObjectFactoryMethod = c.Resolve<Factory.FactoryMethod>();
return new Factory(finalObjectFactoryMethod);
}).As<IFactory>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(Interceptor));
IContainer container = builder.Build();
IFactory factory = container.Resolve<IFactory>();
IFinal final = factory.GetFinalObject(42);
final.Test();
}
}
public interface IDependency{}
public class Dependency: IDependency{}
public interface IFinal
{
void Test();
}
public class Final: IFinal
{
public Final(IDependency dependency, int runtimeArgument){}
public void Test(){}
}
public interface IFactory
{
IFinal GetFinalObject(int runtimeArgument);
}
public class Factory: IFactory
{
public delegate IFinal FactoryMethod(int runtimeArgument);
readonly FactoryMethod _finalObjectFactoryMethod;
public Factory(FactoryMethod finalObjectFactoryMethod)
{
_finalObjectFactoryMethod = finalObjectFactoryMethod;
}
public IFinal GetFinalObject(int runtimeArgument)
{
return _finalObjectFactoryMethod(runtimeArgument);
}
}
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"call {invocation.Method.Name}");
invocation.Proceed();
Console.WriteLine($"return from {invocation.Method.Name}");
}
}
拦截器现在将其写入控制台:
call GetFinalObject
return from GetFinalObject
call Test
return from Test
也许这可以帮助其他人。
答案 1 :(得分:1)
您必须将工厂 delegate
添加到Final
:
public class Final : IFinal
{
public delegate IFinal Factory(int runtimeArgument);
public Final(IDependency dependency, int runtimeArgument) { }
public void Test() { }
}
Autofac非常聪明,可以填充其他参数,因此您的工厂委托只能在运行时指定参数,而其他参数可以通过 magic 解析。
然后注册类型:
builder
.RegisterType<Final>()
.As<IFinal>();
以下是完整的示例:
public static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder
.RegisterType<Dependency>()
.As<IDependency>();
builder
.RegisterType<Final>()
.As<IFinal>();
using(var container = builder.Build())
using (var scope = container.BeginLifetimeScope())
{
var finalFactory = scope.Resolve<Final.Factory>();
IFinal final = finalFactory(42);
}
}
根本不需要Factory
课程。委托可以直接从scope
解析,也可以使用与任何其他依赖相同的方式,并由Autofac注入。只是juse Final.Factory
作为你的依赖。