I have the following classes inside the Assembly AutofacDotMemory
public interface IOutput:IDisposable
{
void Write(string content);
}
public class ConsoleOutput : IOutput
{
public void Write(string content)
{
Console.WriteLine(content);
}
public void Dispose()
{
// TODO release managed resources here
}
}
public interface IDateWriter:IDisposable
{
void WriteDate();
}
public class TodayWriter : IDateWriter
{
private IOutput _output;
public TodayWriter( IOutput output)
{
this._output = output;
}
public void WriteDate()
{
this._output.Write(DateTime.Today.ToShortDateString());
}
public void Dispose()
{
// TODO release managed resources here
}
}
And in my another test assembly I've also referred to Autofac and I try to use ExternallyOwned at assembly scanning level, with the following test code:
[Test]
public void ExternallyOwnedTest()
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(IDateWriter).Assembly)
.ExternallyOwned();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<TodayWriter>().As<IDateWriter>();
var container = builder.Build();
var registration = container.ComponentRegistry.TryGetRegistration(new TypedService(typeof(IDateWriter)), out var foundRegistration);
TestContext.WriteLine(registration);
var isExternallyOwned = registration && foundRegistration.Ownership == InstanceOwnership.ExternallyOwned;
Assert.IsTrue(isExternallyOwned, $"{nameof(TodayWriter)} is not externally owned");
container.Dispose();
}
And the test fails because TodayWriter
is not ExternallyOwned.
But if I change the registration code to the below, so that it's done on per registration type basis:
var builder = new ContainerBuilder();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<TodayWriter>().As<IDateWriter>().ExternallyOwned(); //now this works
var container = builder.Build();
var registration = container.ComponentRegistry.TryGetRegistration(new TypedService(typeof(IDateWriter)), out var foundRegistration);
TestContext.WriteLine(registration);
var isExternallyOwned = registration && foundRegistration.Ownership == InstanceOwnership.ExternallyOwned;
Assert.IsTrue(isExternallyOwned, $"{nameof(TodayWriter)} is not externally owned");
container.Dispose();
And now this test passes because TodayWriter
is externally owned.
How to ensure that all of the types in a given assembly ( or at least the majority of the types, subjected to a Where
filter condition) is registered as ExternallyOwned? I don't want to go through all of the registered type and add an ExternallyOwned keyword there.
In your test...
builder.RegisterAssemblyTypes(typeof(IDateWriter).Assembly)
.ExternallyOwned();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<TodayWriter>().As<IDateWriter>();
You registered TodayWriter
twice. Once through the assembly scanning, once manually.
In the assembly scanning it got registered as ExternallyOwned
. But then you overrode that and registered it as normal, which is not ExternallyOwned
. In registrations, last in wins.