Fix WasAutoCreated, and use to allow the user to replace framework-created bindings

This commit is contained in:
Antony Male 2014-03-05 13:27:04 +00:00
parent cc8e3343cf
commit 228147b634
4 changed files with 49 additions and 13 deletions

View File

@ -28,7 +28,14 @@ namespace Stylet
base.Start();
var builder = new StyletIoCBuilder();
// Mark these as auto-bindings, so the user can replace them if they want
builder.Bind(typeof(IWindowManager), true).To<WindowManager>().InSingletonScope();
builder.Bind(typeof(IEventAggregator), true).To<EventAggregator>().InSingletonScope();
builder.Bind(typeof(IViewManager), true).To<ViewManager>().InSingletonScope();
this.ConfigureIoC(builder);
this.container = builder.BuildContainer();
}
@ -36,16 +43,12 @@ namespace Stylet
/// Override to add your own types to the IoC container.
/// </summary>
/// <remarks>
/// Don't call the base method if you want to set up your own bindings for IWindowManager, IEventAggregator, IViewManager
/// Don't call the base method if you don't want to auto-self-bind all concrete types
/// </remarks>
/// <param name="builder"></param>
protected virtual void ConfigureIoC(IStyletIoCBuilder builder)
{
builder.Autobind(AssemblySource.Assemblies);
builder.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
builder.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
builder.Bind<IViewManager>().To<ViewManager>().InSingletonScope();
}
/// <summary>

View File

@ -34,7 +34,12 @@ namespace StyletIoC
public IRegistrationCollection AddRegistration(IRegistration registration)
{
return new RegistrationCollection(new List<IRegistration>() { this.registration, registration });
// If we were auto-created, and the newcomer is not, replace us with them
// This allows an explicit binding to replace an auto-created one
if (this.registration.WasAutoCreated && !registration.WasAutoCreated)
return new SingleRegistration(registration);
else
return new RegistrationCollection(new List<IRegistration>() { this.registration, registration });
}
}

View File

@ -78,10 +78,12 @@ namespace StyletIoC
{
private Type serviceType;
private BuilderBindingBase builderBinding;
private bool wasAutoCreated;
public BuilderBindTo(Type serviceType)
public BuilderBindTo(Type serviceType, bool wasAutoCreated)
{
this.serviceType = serviceType;
this.wasAutoCreated = wasAutoCreated;
}
public IInScopeOrWithKey ToSelf()
@ -96,19 +98,19 @@ namespace StyletIoC
public IInScopeOrWithKey To(Type implementationType)
{
this.builderBinding = new BuilderTypeBinding(this.serviceType, implementationType);
this.builderBinding = new BuilderTypeBinding(this.serviceType, implementationType) { WasAutoCreated = this.wasAutoCreated };
return this.builderBinding;
}
public IInScopeOrWithKey ToFactory<TImplementation>(Func<IContainer, TImplementation> factory)
{
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.serviceType, factory);
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.serviceType, factory) { WasAutoCreated = this.wasAutoCreated };
return this.builderBinding;
}
public IWithKey ToAbstractFactory()
{
this.builderBinding = new AbstractFactoryBinding(this.serviceType);
this.builderBinding = new AbstractFactoryBinding(this.serviceType) { WasAutoCreated = this.wasAutoCreated };
return this.builderBinding;
}
@ -116,7 +118,7 @@ namespace StyletIoC
{
if (assemblies == null || assemblies.Length == 0)
assemblies = new[] { Assembly.GetCallingAssembly() };
this.builderBinding = new BuilderToAllImplementationsBinding(this.serviceType, assemblies);
this.builderBinding = new BuilderToAllImplementationsBinding(this.serviceType, assemblies) { WasAutoCreated = true };
return this.builderBinding;
}
@ -128,6 +130,8 @@ namespace StyletIoC
internal abstract class BuilderBindingBase : IInScopeOrWithKey, IWithKey
{
public bool WasAutoCreated { get; set; }
protected Type serviceType;
protected bool isSingleton;
protected string key;
@ -189,6 +193,8 @@ namespace StyletIoC
{
var creator = new TypeCreator(implementationType, container);
IRegistration registration = this.isSingleton ? (IRegistration)new SingletonRegistration(creator) : (IRegistration)new TransientRegistration(creator);
registration.WasAutoCreated = this.WasAutoCreated;
container.AddRegistration(new TypeKey(this.serviceType, this.key ?? creator.AttributeKey), registration);
}
}
@ -233,6 +239,8 @@ namespace StyletIoC
{
var creator = new FactoryCreator<TImplementation>(this.factory, container);
IRegistration registration = this.isSingleton ? (IRegistration)new SingletonRegistration(creator) : (IRegistration)new TransientRegistration(creator);
registration.WasAutoCreated = this.WasAutoCreated;
container.AddRegistration(new TypeKey(this.serviceType, this.key), registration);
}
}
@ -277,6 +285,8 @@ namespace StyletIoC
var factoryType = container.GetFactoryForType(this.serviceType);
var creator = new TypeCreator(factoryType, container);
var registration = new SingletonRegistration(creator);
registration.WasAutoCreated = this.WasAutoCreated;
container.AddRegistration(new TypeKey(this.serviceType, this.key), registration);
}
}
@ -330,7 +340,12 @@ namespace StyletIoC
/// <param name="serviceType">Service to bind</param>
public IBindTo Bind(Type serviceType)
{
var builderBindTo = new BuilderBindTo(serviceType);
return this.Bind(serviceType, false);
}
internal IBindTo Bind(Type serviceType, bool isAutoBinding)
{
var builderBindTo = new BuilderBindTo(serviceType, isAutoBinding);
this.bindings.Add(builderBindTo);
return builderBindTo;
}
@ -361,7 +376,7 @@ namespace StyletIoC
// Don't care if binding fails - we're likely to hit a few of these
try
{
this.Bind(cls).To(cls);
this.Bind(cls, true).To(cls);
}
catch (StyletIoCRegistrationException e)
{

View File

@ -104,5 +104,18 @@ namespace StyletUnitTests
var result = ioc.Get<C3>("Key");
Assert.IsInstanceOf<C3>(result);
}
[Test]
public void AutobindingBindingsCanBeReplaced()
{
var builder = new StyletIoCBuilder();
builder.Autobind();
builder.Bind<C11>().ToSelf().InSingletonScope();
var ioc = builder.BuildContainer();
var result1 = ioc.Get<C11>();
var result2 = ioc.Get<C11>();
Assert.AreEqual(result2, result1);
}
}
}