根据Gang of Four的说法,工厂方法模式用于
定义用于创建对象的接口,但让子类决定 要实例化的类。 Factory方法允许类延迟 它用于子类的实例化。
相反,我使用它来进行具有耗时构造函数的类的异步构造。让我们假设这个类
public class MyClass
{
private readonly IA _a;
private MyClass(IA a)
{
_a = a;
}
public static MyClass Create(IA a)
{
var instance = new MyClass(a);
instance.InitializeAsync().Wait();
return instance;
}
public static async Task<MyClass> CreateAsync(IA a)
{
var instance = new MyClass(a);
await instance.InitializeAsync();
return instance;
}
private Task InitializeAsync()
{
return Task.Run(() =>
{
Task.Delay(5000).Wait();
});
}
}
构造函数是私有的,因此您必须通过其中一个Create方法获取实例。要异步请求实例,我将使用await MyClass.CreateAsync()
来创建此类的实例。确实存在未初始化实例是坏事的用例,工厂方法模式可以为我们解决这个问题。
在这种简化的情况下MyClass
只有一个依赖IA
我可以按如下方式注册该组件:
_builder.Register(c => MyClass.Create(c.Resolve<IA>()))
.As<MyClass>()
.InstancePerDependency();
_builder.Register(c => MyClass.CreateAsync(c.Resolve<IA>()))
.As<Task<MyClass>>()
.InstancePerDependency();
我已经注册了同步创建和异步创建。让我们通过让Autofac为我们解析类来举例说明异步创建:
var myInstance = await IoCProxy.RootLifetimeScope.Resolve<Task<MyClass>>();
到目前为止,我对这个解决方案非常满意。我可以隐藏调用以创建内部autofac注册,因此对于解析MyClass的人来说,语法将正常,但具有能够await
的额外好处。
我唯一的问题是我被迫手动解决Create()
方法中定义的每个依赖项。对于这个例子,我只有一个依赖IA
,但对于我的许多类,我注入了10多个依赖项。对于构造函数注入,Autofac使用反射来遍历所有构造函数参数,但在使用Register()
时,我回避了这个功能。还有另一种方法可以让Autofac自动为我解析参数吗?