mirror of https://github.com/AMT-Cheif/Stylet.git
Get rid of the whole WasAutoCreated thing
The builder now has a concept of a weak binding, which can be replaced by the builder. Compile() now either throws for any error, or ignores all error, regardless of how that type was registered.
This commit is contained in:
parent
d4e563efab
commit
9e3c13cede
|
@ -30,9 +30,9 @@ namespace Stylet
|
|||
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();
|
||||
builder.BindWeak(typeof(IWindowManager)).To<WindowManager>().InSingletonScope();
|
||||
builder.BindWeak(typeof(IEventAggregator)).To<EventAggregator>().InSingletonScope();
|
||||
builder.BindWeak(typeof(IViewManager)).To<ViewManager>().InSingletonScope();
|
||||
|
||||
this.ConfigureIoC(builder);
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace StyletIoC
|
|||
internal interface IRegistration
|
||||
{
|
||||
Type Type { get; }
|
||||
bool WasAutoCreated { get; set; }
|
||||
Func<object> GetGenerator();
|
||||
Expression GetInstanceExpression();
|
||||
}
|
||||
|
@ -21,7 +20,6 @@ namespace StyletIoC
|
|||
protected ICreator creator;
|
||||
|
||||
public Type Type { get { return this.creator.Type; } }
|
||||
public bool WasAutoCreated { get; set; }
|
||||
|
||||
protected Func<object> generator { get; set; }
|
||||
|
||||
|
@ -97,7 +95,6 @@ namespace StyletIoC
|
|||
|
||||
public string Key { get; set; }
|
||||
public Type Type { get; private set; }
|
||||
public bool WasAutoCreated { get; set; }
|
||||
|
||||
private Expression expression;
|
||||
private Func<object> generator;
|
||||
|
|
|
@ -34,12 +34,7 @@ namespace StyletIoC
|
|||
|
||||
public IRegistrationCollection AddRegistration(IRegistration 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 });
|
||||
return new RegistrationCollection(new List<IRegistration>() { this.registration, registration });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,14 +65,8 @@ namespace StyletIoC
|
|||
lock (this.registrations)
|
||||
{
|
||||
// Is there an existing registration for this type?
|
||||
var existingRegistration = this.registrations.FirstOrDefault(x => x.Type == registration.Type);
|
||||
if (existingRegistration != null)
|
||||
{
|
||||
if (existingRegistration.WasAutoCreated)
|
||||
this.registrations.Remove(existingRegistration);
|
||||
else
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found.", registration.Type.Name));
|
||||
}
|
||||
if (this.registrations.Any(x => x.Type == registration.Type))
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found.", registration.Type.Name));
|
||||
this.registrations.Add(registration);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -76,19 +76,20 @@ namespace StyletIoC
|
|||
|
||||
internal class BuilderBindTo : IBindTo
|
||||
{
|
||||
private Type serviceType;
|
||||
public Type ServiceType { get; private set; }
|
||||
private BuilderBindingBase builderBinding;
|
||||
private bool wasAutoCreated;
|
||||
public bool IsWeak { get; private set; }
|
||||
public string Key { get { return this.builderBinding.Key; } }
|
||||
|
||||
public BuilderBindTo(Type serviceType, bool wasAutoCreated)
|
||||
public BuilderBindTo(Type serviceType, bool isWeak)
|
||||
{
|
||||
this.serviceType = serviceType;
|
||||
this.wasAutoCreated = wasAutoCreated;
|
||||
this.ServiceType = serviceType;
|
||||
this.IsWeak = isWeak;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKey ToSelf()
|
||||
{
|
||||
return this.To(this.serviceType);
|
||||
return this.To(this.ServiceType);
|
||||
}
|
||||
|
||||
public IInScopeOrWithKey To<TImplementation>()
|
||||
|
@ -98,19 +99,19 @@ namespace StyletIoC
|
|||
|
||||
public IInScopeOrWithKey To(Type implementationType)
|
||||
{
|
||||
this.builderBinding = new BuilderTypeBinding(this.serviceType, implementationType) { WasAutoCreated = this.wasAutoCreated };
|
||||
this.builderBinding = new BuilderTypeBinding(this.ServiceType, implementationType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKey ToFactory<TImplementation>(Func<IContainer, TImplementation> factory)
|
||||
{
|
||||
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.serviceType, factory) { WasAutoCreated = this.wasAutoCreated };
|
||||
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.ServiceType, factory);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IWithKey ToAbstractFactory()
|
||||
{
|
||||
this.builderBinding = new AbstractFactoryBinding(this.serviceType) { WasAutoCreated = this.wasAutoCreated };
|
||||
this.builderBinding = new AbstractFactoryBinding(this.ServiceType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,7 @@ namespace StyletIoC
|
|||
{
|
||||
if (assemblies == null || assemblies.Length == 0)
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
this.builderBinding = new BuilderToAllImplementationsBinding(this.serviceType, assemblies) { WasAutoCreated = true };
|
||||
this.builderBinding = new BuilderToAllImplementationsBinding(this.ServiceType, assemblies);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
|
@ -130,11 +131,9 @@ namespace StyletIoC
|
|||
|
||||
internal abstract class BuilderBindingBase : IInScopeOrWithKey, IWithKey
|
||||
{
|
||||
public bool WasAutoCreated { get; set; }
|
||||
|
||||
protected Type serviceType;
|
||||
protected bool isSingleton;
|
||||
protected string key;
|
||||
public string Key { get; protected set; }
|
||||
|
||||
public BuilderBindingBase(Type serviceType)
|
||||
{
|
||||
|
@ -148,7 +147,7 @@ namespace StyletIoC
|
|||
|
||||
IInScope IInScopeOrWithKey.WithKey(string key)
|
||||
{
|
||||
this.key = key;
|
||||
this.Key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -187,21 +186,20 @@ namespace StyletIoC
|
|||
if (this.serviceType.IsGenericTypeDefinition)
|
||||
{
|
||||
var unboundGeneric = new UnboundGeneric(implementationType, container, this.isSingleton);
|
||||
container.AddUnboundGeneric(new TypeKey(serviceType, key), unboundGeneric);
|
||||
container.AddUnboundGeneric(new TypeKey(serviceType, Key), unboundGeneric);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key ?? creator.AttributeKey), registration);
|
||||
}
|
||||
}
|
||||
|
||||
void IWithKey.WithKey(string key)
|
||||
{
|
||||
this.key = key;
|
||||
this.Key = key;
|
||||
}
|
||||
|
||||
public abstract void Build(StyletIoCContainer container);
|
||||
|
@ -239,9 +237,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);
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,9 +282,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);
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,12 +336,17 @@ namespace StyletIoC
|
|||
/// <param name="serviceType">Service to bind</param>
|
||||
public IBindTo Bind(Type serviceType)
|
||||
{
|
||||
return this.Bind(serviceType, false);
|
||||
return this.BindInternal(serviceType, false);
|
||||
}
|
||||
|
||||
internal IBindTo Bind(Type serviceType, bool isAutoBinding)
|
||||
internal IBindTo BindWeak(Type serviceType)
|
||||
{
|
||||
var builderBindTo = new BuilderBindTo(serviceType, isAutoBinding);
|
||||
return this.BindInternal(serviceType, true);
|
||||
}
|
||||
|
||||
internal IBindTo BindInternal(Type serviceType, bool isWeak)
|
||||
{
|
||||
var builderBindTo = new BuilderBindTo(serviceType, isWeak);
|
||||
this.bindings.Add(builderBindTo);
|
||||
return builderBindTo;
|
||||
}
|
||||
|
@ -376,7 +377,7 @@ namespace StyletIoC
|
|||
// Don't care if binding fails - we're likely to hit a few of these
|
||||
try
|
||||
{
|
||||
this.Bind(cls, true).To(cls);
|
||||
this.BindWeak(cls).To(cls);
|
||||
}
|
||||
catch (StyletIoCRegistrationException e)
|
||||
{
|
||||
|
@ -407,7 +408,10 @@ namespace StyletIoC
|
|||
container.AddRegistration(new TypeKey(typeof(IContainer), null), new SingletonRegistration(new FactoryCreator<StyletIoCContainer>(c => container, container)));
|
||||
container.AddRegistration(new TypeKey(typeof(StyletIoCContainer), null), new SingletonRegistration(new FactoryCreator<StyletIoCContainer>(c => container, container)));
|
||||
|
||||
foreach (var binding in this.bindings)
|
||||
// For each TypeKey, we remove any weak bindings if there are any strong bindings
|
||||
var groups = this.bindings.GroupBy(x => new { Key = x.Key, Type = x.ServiceType });
|
||||
var filtered = groups.SelectMany(group => group.Any(x => !x.IsWeak) ? group.Where(x => !x.IsWeak) : group);
|
||||
foreach (var binding in filtered)
|
||||
{
|
||||
binding.Build(container);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ namespace StyletIoC
|
|||
/// <summary>
|
||||
/// Compile all known bindings (which would otherwise be compiled when needed), checking the dependency graph for consistency
|
||||
/// </summary>
|
||||
void Compile();
|
||||
/// <param name="throwOnError">If true, throw if we fail to compile a type</param>
|
||||
void Compile(bool throwOnError = true);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch a single instance of the specified type
|
||||
|
@ -121,7 +122,7 @@ namespace StyletIoC
|
|||
/// <summary>
|
||||
/// Compile all known bindings (which would otherwise be compiled when needed), checking the dependency graph for consistency
|
||||
/// </summary>
|
||||
public void Compile()
|
||||
public void Compile(bool throwOnError = true)
|
||||
{
|
||||
foreach (var kvp in this.registrations)
|
||||
{
|
||||
|
@ -133,10 +134,8 @@ namespace StyletIoC
|
|||
}
|
||||
catch (StyletIoCFindConstructorException)
|
||||
{
|
||||
// If we can't resolve an auto-created type, that's fine
|
||||
// Don't remove it from the list of types - that way they'll get a
|
||||
// decent error message if they actually try and resolve it
|
||||
if (!registration.WasAutoCreated)
|
||||
// If they've asked us to be quiet, we will
|
||||
if (throwOnError)
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -414,14 +413,8 @@ namespace StyletIoC
|
|||
lock (unboundGenerics)
|
||||
{
|
||||
// Is there an auto-registration for this type? If so, remove it
|
||||
var existingEntry = unboundGenerics.Where(x => x.Type == unboundGeneric.Type).FirstOrDefault();
|
||||
if (existingEntry != null)
|
||||
{
|
||||
if (existingEntry.WasAutoCreated)
|
||||
unboundGenerics.Remove(existingEntry);
|
||||
else
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found", typeKey.Type.Name));
|
||||
}
|
||||
if (unboundGenerics.Any(x => x.Type == unboundGeneric.Type))
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found", typeKey.Type.Name));
|
||||
|
||||
unboundGenerics.Add(unboundGeneric);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace StyletIoC
|
|||
internal class UnboundGeneric
|
||||
{
|
||||
private StyletIoCContainer container;
|
||||
public bool WasAutoCreated { get; set; }
|
||||
public string Key { get; set; }
|
||||
public Type Type { get; private set; }
|
||||
public int NumTypeParams
|
||||
|
@ -28,9 +27,9 @@ namespace StyletIoC
|
|||
public IRegistration CreateRegistrationForType(Type boundType)
|
||||
{
|
||||
if (this.IsSingleton)
|
||||
return new SingletonRegistration(new TypeCreator(boundType, this.container)) { WasAutoCreated = this.WasAutoCreated };
|
||||
return new SingletonRegistration(new TypeCreator(boundType, this.container));
|
||||
else
|
||||
return new TransientRegistration(new TypeCreator(boundType, this.container)) { WasAutoCreated = this.WasAutoCreated };
|
||||
return new TransientRegistration(new TypeCreator(boundType, this.container));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue