I wanted to know what is the proper usage of InstancePerOwned<TService>()
in Autofac. How can I use that when resolving dependencies?
public interface IAnotherService
{
int Id { get; set; }
string Lable { get; set; }
}
public class AnotherService : IAnotherService,IDisposable
{
public int Id { get; set; }
public string Lable { get; set; }
public AnotherService(/* loads of dependent components*/)
{
}
public override string ToString()
{
return string.Format("My Id is:{0} and my lable is {1}", Id, Lable);
}
public void Dispose()
{
// Another Service is Disposing ;
}
}
public interface IMyService
{
void DoSomething();
}
// MyService class depends on IAnotherService
// MyService class is a huge and long-lived class where we have just ommited lots of other implementations
public class MyService : IMyService
{
private readonly IAnotherService _anotherService;
public MyService(IAnotherService anotherService)
{
_anotherService = anotherService;
}
public Void DoSomething()
{
Console.WriteLine(_anotherService.ToString());
}
//
//
//
// The rest of the class
//
//
//
//
}
In above code MyService class depends on IAnotherService. So somehow in your dependency registration you would say
builder.RegisterType<AnotherService>().As<IAnotherService>().InstancePerDependency();
This makes sure anytime an instance of MyService is instantiated or resolved using Autofac, one instance of AnotherService will be resolved beforehand within the lifetimescope where MyService is being instantiated.
While MyService is alive, in other word, it's parrent lifetimescope is alive, _anotherService needs to be alive whether or not it's being used in the rest of the code of MyService.
Note that an Owned instance of a service is and object instantiated from a just-newly-created lifetimescope.
Owned<IAnotherService> _anotherService ;
The good point about this object (_anotherService ) is that before its instantiation
an instance of AnotherService is instantiated within newly created lifetimescope in step1
new AnotherService instance and its container lifetimescope will be bound and form an instance of Owned and injected to MyService class.
Anytime in the lifetime of MyService where you no longer need _anotherService you can call Dispose() method of it directly like
_anotherService.Dispose() ;
Once you dispose it, that object and the bound lifetimescope and any other child or dependant object of that lifetimescope will be gone and released.
So you would not have to bear the unnecessary presence of _anotherService and it's loads of dependent components
So our constructor part of the MyService should be like following:
private readonly Owned<IAnotherService> _anotherService;
public MyService(Owned<IAnotherService> anotherService)
{
_anotherService = anotherService;
}
Meaning that we have a lifetimescope bound to the anotherService which anotherService is instantiated within. If you want to force all the newly created objects and resolved components inside above lifetimescope to share the same instance of anotherService then you have to use InstancePerOwned at the time of registration like this
builder.RegisterType<AnotherService>().As<IAnotherService>().InstancePerOwned<IAnotherService>();
and once you register AnotherService as InstancePerOwned you cannot pass pure IAnotherInstance and you will have to pass it like Owned or else you get exception.
you can read more of this on An Autofac Lifetime Primer
EDIT: Fixed one-character typo (edits must be at least 6 characters!)