Is there a way I can either specify a different default lifetime manager
Yes, you can use a container extension that will use a different lifetime manager. See Request for configurable default lifetimemanager for an example.
or disable the default auto-resolution behavior completely and limit the container to types I register myself
Yes, a container extension can do this as well.
First during explicit registration record the BuildKey of the registration. Then before creating the object check if the BuildKey was explicitly registered.
public class RegistrationTrackingExtension : UnityContainerExtension
{
private ConcurrentDictionary<NamedTypeBuildKey, bool> registrations =
new ConcurrentDictionary<NamedTypeBuildKey, bool>();
protected override void Initialize()
{
base.Context.Registering += Context_Registering;
base.Context.Strategies.Add(
new ValidateRegistrationStrategy(this.registrations), UnityBuildStage.PreCreation);
}
private void Context_Registering(object sender, RegisterEventArgs e)
{
var buildKey = new NamedTypeBuildKey(e.TypeTo, e.Name);
this.registrations.AddOrUpdate(buildKey, true, (key, oldValue) => true);
}
public class ValidateRegistrationStrategy : BuilderStrategy
{
private ConcurrentDictionary<NamedTypeBuildKey, bool> registrations;
public ValidateRegistrationStrategy(ConcurrentDictionary<NamedTypeBuildKey, bool> registrations)
{
this.registrations = registrations;
}
public override void PreBuildUp(IBuilderContext context)
{
if (!this.registrations.ContainsKey(context.BuildKey))
{
Exception e = new Exception("Type was not explicitly registered in the container.");
throw new ResolutionFailedException(context.BuildKey.Type, context.BuildKey.Name, e, context);
}
}
}
}
Then add the extension, register some classes and resolve. If the class was not explicitly registered then an exception will be thrown.
IUnityContainer container = new UnityContainer();
// Add container extension
container.AddNewExtension<RegistrationTrackingExtension>();
// Register types
container.RegisterType<MyClass>();
container.RegisterType<IMyClass, MyClass>();
container.RegisterType<IMyClass, MyClass>("A");
// These succeed because they were explicitly registered
container.Resolve<IMyClass>();
container.Resolve<IMyClass>("A");
container.Resolve<MyClass>();
// MyClass2 was not registered so this will throw an exception
container.Resolve<MyClass2>();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…