BACKGROUND
According to Gang of Four the factory method pattern is used for
Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses.
Instead I am using it to have asynchronous construction of classes that have time consuming constructors. Lets assume this class
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();
});
}
}
The constructor is private so you are forced to get instances through one of the Create methods. To request an instance asynchronously I would use await MyClass.CreateAsync() to create an instance of this class. There are indeed use cases where uninitialized instances are a bad thing, and the factory method pattern can solve this for us.
In this simplified case where MyClass only has one dependency IA I can register the component as follows:
_builder.Register(c => MyClass.Create(c.Resolve<IA>()))
.As<MyClass>()
.InstancePerDependency();
_builder.Register(c => MyClass.CreateAsync(c.Resolve<IA>()))
.As<Task<MyClass>>()
.InstancePerDependency();
I have registered both sync creation and async creation. Lets exemplify async creation by letting Autofac resolve the class for us:
var myInstance = await IoCProxy.RootLifetimeScope.Resolve<Task<MyClass>>();
I am very happy with this solution so far. I can hide the call to create inside autofac registration, so for someone resolving MyClass, the syntax will be just as normal, but with the added benefit of being able to await.
PROBLEM
My only problem is that I am forced to manually resolve each of the dependencies defined in the Create() method. For this example I have only one dependency IA but for many of my classes I am injecting 10+ dependencies. For constructor injection Autofac uses reflection to walk through all of the constructor arguments, but when using Register() I sidestep this functionality. Is there another way to ask Autofac to automatically resolve arguments for me?
Aucun commentaire:
Enregistrer un commentaire