mirror of https://github.com/AMT-Cheif/Stylet.git
Split the builder up into separate files, and move a couple of things out to extension methods
This commit is contained in:
parent
f9a16df8be
commit
5fd04a410e
|
@ -47,15 +47,21 @@
|
|||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="StyletIoC\Builder\ICreator.cs" />
|
||||
<Compile Include="StyletIoC\Builder\IRegistration.cs" />
|
||||
<Compile Include="StyletIoC\Creation\ICreator.cs" />
|
||||
<Compile Include="StyletIoC\Creation\IRegistration.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\AbstractFactoryBinding.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\BuilderBindingBase.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\BuilderBindTo.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\BuilderFactoryBinding.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\BuilderToAllImplementationsBinding.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Builders\BuilderTypeBinding.cs" />
|
||||
<Compile Include="StyletIoC\Internal\IRegistrationCollection.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Creators\AbstractFactoryCreator.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Creators\CreatorBase.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Creators\FactoryCreator.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Creators\TypeCreator.cs" />
|
||||
<Compile Include="StyletIoC\Internal\DelegatingDictionary.cs" />
|
||||
<Compile Include="StyletIoC\Builder\IRegistrationContext.cs" />
|
||||
<Compile Include="StyletIoC\Creation\IRegistrationContext.cs" />
|
||||
<Compile Include="StyletIoC\Internal\RegistrationCollections\RegistrationCollection.cs" />
|
||||
<Compile Include="StyletIoC\Internal\RegistrationCollections\SingleRegistration.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Registrations\FuncNoKeyRegistration.cs" />
|
||||
|
@ -113,7 +119,7 @@
|
|||
<Compile Include="PropertyChangedExtensions.cs" />
|
||||
<Compile Include="Screen.cs" />
|
||||
<Compile Include="ScreenExtensions.cs" />
|
||||
<Compile Include="StyletIoC\Builder\BuilderUpper.cs" />
|
||||
<Compile Include="StyletIoC\Creation\BuilderUpper.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCBuilder.cs" />
|
||||
<Compile Include="StyletIoC\Internal\Container.cs" />
|
||||
<Compile Include="StyletIoC\Internal\UnboundGeneric.cs" />
|
||||
|
@ -132,6 +138,7 @@
|
|||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace StyletIoC.Builder
|
||||
namespace StyletIoC.Creation
|
||||
{
|
||||
/// <summary>
|
||||
/// A BuilderUpper knows how to build up an object - that is, populate all parameters decorated with [Inject]
|
|
@ -5,7 +5,7 @@ using System.Linq.Expressions;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Builder
|
||||
namespace StyletIoC.Creation
|
||||
{
|
||||
/// <summary>
|
||||
/// An ICreator is responsible for creating an instance of an object on demand
|
|
@ -5,7 +5,7 @@ using System.Linq.Expressions;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Builder
|
||||
namespace StyletIoC.Creation
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate used to create an IRegistration
|
|
@ -5,7 +5,7 @@ using System.Linq.Expressions;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Builder
|
||||
namespace StyletIoC.Creation
|
||||
{
|
||||
/// <summary>
|
||||
/// Context used by IRegistration and ICreator to get things needed to create instances, etc
|
|
@ -0,0 +1,29 @@
|
|||
using StyletIoC.Internal.Creators;
|
||||
using StyletIoC.Internal.Registrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal class AbstractFactoryBinding : BuilderBindingBase
|
||||
{
|
||||
public AbstractFactoryBinding(Type serviceType)
|
||||
: base(serviceType)
|
||||
{
|
||||
if (serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("Unbound generic type {0} can't be used as an abstract factory", serviceType.GetDescription()));
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var factoryType = container.GetFactoryForType(this.serviceType);
|
||||
var creator = new AbstractFactoryCreator(factoryType);
|
||||
var registration = new TransientRegistration(creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal class BuilderBindTo : IBindTo
|
||||
{
|
||||
public Type ServiceType { get; private set; }
|
||||
private BuilderBindingBase builderBinding;
|
||||
public bool IsWeak { get { return this.builderBinding.IsWeak; } }
|
||||
public string Key { get { return this.builderBinding.Key; } }
|
||||
|
||||
public BuilderBindTo(Type serviceType)
|
||||
{
|
||||
this.ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToSelf()
|
||||
{
|
||||
return this.To(this.ServiceType);
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding To(Type implementationType)
|
||||
{
|
||||
this.builderBinding = new BuilderTypeBinding(this.ServiceType, implementationType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToFactory<TImplementation>(Func<IRegistrationContext, TImplementation> factory)
|
||||
{
|
||||
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.ServiceType, factory);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IWithKey ToAbstractFactory()
|
||||
{
|
||||
this.builderBinding = new AbstractFactoryBinding(this.ServiceType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
if (assemblies == null || !assemblies.Any())
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
this.builderBinding = new BuilderToAllImplementationsBinding(this.ServiceType, assemblies);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
internal void Build(Container container)
|
||||
{
|
||||
this.builderBinding.Build(container);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal.Creators;
|
||||
using StyletIoC.Internal.Registrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal abstract class BuilderBindingBase : IInScopeOrWithKeyOrAsWeakBinding, IWithKey
|
||||
{
|
||||
protected Type serviceType;
|
||||
protected RegistrationFactory registrationFactory;
|
||||
public string Key { get; protected set; }
|
||||
public bool IsWeak { get; protected set; }
|
||||
|
||||
public BuilderBindingBase(Type serviceType)
|
||||
{
|
||||
this.serviceType = serviceType;
|
||||
|
||||
// Default is transient
|
||||
this.registrationFactory = (ctx, creator, key) => new TransientRegistration(creator);
|
||||
}
|
||||
|
||||
IAsWeakBinding IInScopeOrAsWeakBinding.WithRegistrationFactory(RegistrationFactory registrationFactory)
|
||||
{
|
||||
if (registrationFactory == null)
|
||||
throw new ArgumentNullException("registrationFactory");
|
||||
this.registrationFactory = registrationFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
IInScopeOrAsWeakBinding IInScopeOrWithKeyOrAsWeakBinding.WithKey(string key)
|
||||
{
|
||||
this.Key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void EnsureType(Type implementationType, Type serviceType = null)
|
||||
{
|
||||
serviceType = serviceType ?? this.serviceType;
|
||||
|
||||
if (!implementationType.IsClass || implementationType.IsAbstract)
|
||||
throw new StyletIoCRegistrationException(String.Format("Type {0} is not a concrete class, and so can't be used to implemented service {1}", implementationType.GetDescription(), serviceType.GetDescription()));
|
||||
|
||||
// Test this first, as it's a bit clearer than hitting 'type doesn't implement service'
|
||||
if (implementationType.IsGenericTypeDefinition)
|
||||
{
|
||||
if (!serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("You can't use an unbound generic type to implement anything that isn't an unbound generic service. Service: {0}, Type: {1}", serviceType.GetDescription(), implementationType.GetDescription()));
|
||||
|
||||
// This restriction may change when I figure out how to pass down the correct type argument
|
||||
if (serviceType.GetTypeInfo().GenericTypeParameters.Length != implementationType.GetTypeInfo().GenericTypeParameters.Length)
|
||||
throw new StyletIoCRegistrationException(String.Format("If you're registering an unbound generic type to an unbound generic service, both service and type must have the same number of type parameters. Service: {0}, Type: {1}", serviceType.GetDescription(), implementationType.GetDescription()));
|
||||
}
|
||||
else if (serviceType.IsGenericTypeDefinition)
|
||||
{
|
||||
if (implementationType.GetGenericArguments().Length > 0)
|
||||
throw new StyletIoCRegistrationException(String.Format("You cannot bind the bound generic type {0} to the unbound generic service {1}", implementationType.GetDescription(), serviceType.GetDescription()));
|
||||
else
|
||||
throw new StyletIoCRegistrationException(String.Format("You cannot bind the non-generic type {0} to the unbound generic service {1}", implementationType.GetDescription(), serviceType.GetDescription()));
|
||||
}
|
||||
|
||||
if (!implementationType.Implements(this.serviceType))
|
||||
throw new StyletIoCRegistrationException(String.Format("Type {0} does not implement service {1}", implementationType.GetDescription(), serviceType.GetDescription()));
|
||||
}
|
||||
|
||||
// Convenience...
|
||||
protected void BindImplementationToService(Container container, Type implementationType, Type serviceType = null)
|
||||
{
|
||||
serviceType = serviceType ?? this.serviceType;
|
||||
|
||||
if (serviceType.IsGenericTypeDefinition)
|
||||
{
|
||||
var unboundGeneric = new UnboundGeneric(implementationType, container, this.registrationFactory);
|
||||
container.AddUnboundGeneric(new TypeKey(serviceType, this.Key), unboundGeneric);
|
||||
}
|
||||
else
|
||||
{
|
||||
var creator = new TypeCreator(implementationType, container);
|
||||
var registration = this.CreateRegistration(container, creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(serviceType, this.Key ?? creator.AttributeKey), registration);
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience...
|
||||
protected IRegistration CreateRegistration(IRegistrationContext registrationContext, ICreator creator)
|
||||
{
|
||||
return this.registrationFactory(registrationContext, creator, this.Key);
|
||||
}
|
||||
|
||||
void IWithKey.WithKey(string key)
|
||||
{
|
||||
this.Key = key;
|
||||
}
|
||||
|
||||
void IAsWeakBinding.AsWeakBinding()
|
||||
{
|
||||
this.IsWeak = true;
|
||||
}
|
||||
|
||||
public abstract void Build(Container container);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal.Creators;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal class BuilderFactoryBinding<TImplementation> : BuilderBindingBase
|
||||
{
|
||||
private Func<IRegistrationContext, TImplementation> factory;
|
||||
|
||||
public BuilderFactoryBinding(Type serviceType, Func<IRegistrationContext, TImplementation> factory)
|
||||
: base(serviceType)
|
||||
{
|
||||
if (this.serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("A factory cannot be used to implement unbound generic type {0}", this.serviceType.GetDescription()));
|
||||
this.EnsureType(typeof(TImplementation));
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var creator = new FactoryCreator<TImplementation>(this.factory, container);
|
||||
var registration = this.CreateRegistration(container, creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal class BuilderToAllImplementationsBinding : BuilderBindingBase
|
||||
{
|
||||
private IEnumerable<Assembly> assemblies;
|
||||
|
||||
public BuilderToAllImplementationsBinding(Type serviceType, IEnumerable<Assembly> assemblies)
|
||||
: base(serviceType)
|
||||
{
|
||||
this.assemblies = assemblies;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var candidates = from type in assemblies.Distinct().SelectMany(x => x.GetTypes())
|
||||
let baseType = type.GetBaseTypesAndInterfaces().FirstOrDefault(x => x == this.serviceType || x.IsGenericType && x.GetGenericTypeDefinition() == this.serviceType)
|
||||
where baseType != null
|
||||
select new { Type = type, Base = baseType.ContainsGenericParameters ? baseType.GetGenericTypeDefinition() : baseType };
|
||||
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.EnsureType(candidate.Type, candidate.Base);
|
||||
this.BindImplementationToService(container, candidate.Type, candidate.Base);
|
||||
}
|
||||
catch (StyletIoCRegistrationException e)
|
||||
{
|
||||
Debug.WriteLine(String.Format("Unable to auto-bind type {0} to {1}: {2}", candidate.Base.Name, candidate.Type.GetDescription(), e.Message), "StyletIoC");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StyletIoC.Internal.Builders
|
||||
{
|
||||
internal class BuilderTypeBinding : BuilderBindingBase
|
||||
{
|
||||
private Type implementationType;
|
||||
|
||||
public BuilderTypeBinding(Type serviceType, Type implementationType)
|
||||
: base(serviceType)
|
||||
{
|
||||
this.EnsureType(implementationType);
|
||||
this.implementationType = implementationType;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
this.BindImplementationToService(container, this.implementationType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal;
|
||||
using StyletIoC.Internal.Registrations;
|
||||
using StyletIoC.Internal.RegistrationCollections;
|
||||
|
@ -380,14 +380,14 @@ namespace StyletIoC.Internal
|
|||
// Couldn't find this type - is it a 'get all' collection type? (i.e. they've put IEnumerable<TypeWeCanResolve> in a ctor param)
|
||||
IRegistration registration;
|
||||
if (!this.TryRetrieveGetAllRegistration(typeKey, out registration))
|
||||
throw new StyletIoCRegistrationException(String.Format("No registrations found for service {0}.", typeKey.Type.Description()));
|
||||
throw new StyletIoCRegistrationException(String.Format("No registrations found for service {0}.", typeKey.Type.GetDescription()));
|
||||
|
||||
// Got this far? Good. There's actually a 'get all' collection type. Proceed with that
|
||||
registrations = new SingleRegistration(registration);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new StyletIoCRegistrationException(String.Format("No registrations found for service {0}.", typeKey.Type.Description()));
|
||||
throw new StyletIoCRegistrationException(String.Format("No registrations found for service {0}.", typeKey.Type.GetDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,7 +402,7 @@ namespace StyletIoC.Internal
|
|||
}
|
||||
catch (StyletIoCRegistrationException e)
|
||||
{
|
||||
throw new StyletIoCRegistrationException(String.Format("{0} Service type: {1}, key: '{2}'", e.Message, typeKey.Type.Description(), typeKey.Key), e);
|
||||
throw new StyletIoCRegistrationException(String.Format("{0} Service type: {1}, key: '{2}'", e.Message, typeKey.Type.GetDescription(), typeKey.Key), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ namespace StyletIoC.Internal
|
|||
}
|
||||
// Is there an existing registration for this type?
|
||||
if (unboundGenerics.Any(x => x.Type == unboundGeneric.Type))
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found", typeKey.Type.Description()));
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found", typeKey.Type.GetDescription()));
|
||||
|
||||
unboundGenerics.Add(unboundGeneric);
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ namespace StyletIoC.Internal
|
|||
{
|
||||
// Not thread-safe, as it's only called from the builder
|
||||
if (!serviceType.IsInterface)
|
||||
throw new StyletIoCCreateFactoryException(String.Format("Unable to create a factory implementing type {0}, as it isn't an interface", serviceType.Description()));
|
||||
throw new StyletIoCCreateFactoryException(String.Format("Unable to create a factory implementing type {0}, as it isn't an interface", serviceType.GetDescription()));
|
||||
|
||||
if (this.factoryBuilder == null)
|
||||
{
|
||||
|
@ -522,7 +522,7 @@ namespace StyletIoC.Internal
|
|||
}
|
||||
catch (TypeLoadException e)
|
||||
{
|
||||
throw new StyletIoCCreateFactoryException(String.Format("Unable to create factory type for interface {0}. Ensure that the interface is public, or add [assembly: InternalsVisibleTo(StyletIoCContainer.FactoryAssemblyName)] to your AssemblyInfo.cs", serviceType.Description()), e);
|
||||
throw new StyletIoCCreateFactoryException(String.Format("Unable to create factory type for interface {0}. Ensure that the interface is public, or add [assembly: InternalsVisibleTo(StyletIoCContainer.FactoryAssemblyName)] to your AssemblyInfo.cs", serviceType.GetDescription()), e);
|
||||
}
|
||||
|
||||
return constructedType;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -47,7 +47,7 @@ namespace StyletIoC.Internal.Creators
|
|||
var ctorsWithAttribute = this.Type.GetConstructors().Where(x => x.GetCustomAttributes(typeof(InjectAttribute), false).Any()).ToList();
|
||||
if (ctorsWithAttribute.Count > 1)
|
||||
{
|
||||
throw new StyletIoCFindConstructorException(String.Format("Found more than one constructor with [Inject] on type {0}.", this.Type.Description()));
|
||||
throw new StyletIoCFindConstructorException(String.Format("Found more than one constructor with [Inject] on type {0}.", this.Type.GetDescription()));
|
||||
}
|
||||
else if (ctorsWithAttribute.Count == 1)
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ namespace StyletIoC.Internal.Creators
|
|||
var key = ((InjectAttribute)ctorsWithAttribute[0].GetCustomAttribute(typeof(InjectAttribute), false)).Key;
|
||||
var cantResolve = ctor.GetParameters().Where(p => !this.parentContext.CanResolve(p.ParameterType, key) && !p.HasDefaultValue).FirstOrDefault();
|
||||
if (cantResolve != null)
|
||||
throw new StyletIoCFindConstructorException(String.Format("Found a constructor with [Inject] on type {0}, but can't resolve parameter '{1}' (of type {2}, and doesn't have a default value).", this.Type.Description(), cantResolve.Name, cantResolve.ParameterType.Description()));
|
||||
throw new StyletIoCFindConstructorException(String.Format("Found a constructor with [Inject] on type {0}, but can't resolve parameter '{1}' (of type {2}, and doesn't have a default value).", this.Type.GetDescription(), cantResolve.Name, cantResolve.ParameterType.GetDescription()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ namespace StyletIoC.Internal.Creators
|
|||
|
||||
if (ctor == null)
|
||||
{
|
||||
throw new StyletIoCFindConstructorException(String.Format("Unable to find a constructor for type {0} which we can call.", this.Type.Description()));
|
||||
throw new StyletIoCFindConstructorException(String.Format("Unable to find a constructor for type {0} which we can call.", this.Type.GetDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ namespace StyletIoC.Internal.Creators
|
|||
}
|
||||
catch (StyletIoCRegistrationException e)
|
||||
{
|
||||
throw new StyletIoCRegistrationException(String.Format("{0} Required by parameter '{1}' of type {2} (which is a {3}).", e.Message, x.Name, this.Type.Description(), x.ParameterType.Description()), e);
|
||||
throw new StyletIoCRegistrationException(String.Format("{0} Required by parameter '{1}' of type {2} (which is a {3}).", e.Message, x.Name, this.Type.GetDescription(), x.ParameterType.GetDescription()), e);
|
||||
}
|
||||
}
|
||||
// For some reason we need this cast...
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal.RegistrationCollections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -30,7 +30,7 @@ namespace StyletIoC.Internal.RegistrationCollections
|
|||
public IRegistrationCollection AddRegistration(IRegistration registration)
|
||||
{
|
||||
if (this.registration.Type == registration.Type)
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found.", registration.Type.Description()));
|
||||
throw new StyletIoCRegistrationException(String.Format("Multiple registrations for type {0} found.", registration.Type.GetDescription()));
|
||||
return new RegistrationCollection(new List<IRegistration>() { this.registration, registration });
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
@ -62,7 +62,7 @@ namespace StyletIoC.Internal.Registrations
|
|||
{
|
||||
Debug.Assert(ctx == this.parentContext);
|
||||
if (this.disposed)
|
||||
throw new ObjectDisposedException(String.Format("ChildContainer registration for type {0}", this.Type.Description()));
|
||||
throw new ObjectDisposedException(String.Format("ChildContainer registration for type {0}", this.Type.GetDescription()));
|
||||
|
||||
if (this.instance != null)
|
||||
return this.instance;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -37,7 +37,7 @@ namespace StyletIoC.Internal.Registrations
|
|||
public override Expression GetInstanceExpression(ParameterExpression registrationContext)
|
||||
{
|
||||
if (this.disposed)
|
||||
throw new ObjectDisposedException(String.Format("Singleton registration for type {0}", this.Type.Description()));
|
||||
throw new ObjectDisposedException(String.Format("Singleton registration for type {0}", this.Type.GetDescription()));
|
||||
|
||||
if (this.instanceExpression != null)
|
||||
return this.instanceExpression;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -5,13 +5,26 @@ using System.Reflection;
|
|||
|
||||
namespace StyletIoC.Internal
|
||||
{
|
||||
internal static class TypeExtensions
|
||||
/// <summary>
|
||||
/// Useful extension methods on Type
|
||||
/// </summary>
|
||||
public static class TypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Return all base types and interfaces implemented by the given type (and its ancestors)
|
||||
/// </summary>
|
||||
/// <param name="type">Type to return base types and interfaces for</param>
|
||||
/// <returns>Base types and interfaces implemented by the given type</returns>
|
||||
public static IEnumerable<Type> GetBaseTypesAndInterfaces(this Type type)
|
||||
{
|
||||
return type.GetInterfaces().Concat(type.GetBaseTypes());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all base types implemented by the given type (and their base types, etc)
|
||||
/// </summary>
|
||||
/// <param name="type">Type to interrogate</param>
|
||||
/// <returns>Base types implemented by the given type</returns>
|
||||
public static IEnumerable<Type> GetBaseTypes(this Type type)
|
||||
{
|
||||
for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType)
|
||||
|
@ -20,6 +33,15 @@ namespace StyletIoC.Internal
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if any of the type's base types or interfaces is equal to the given service type. Also checks generic types
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, given I1{T} and C1{T} : I1{T}, typeof(C1{int}).Implemements(typeof(I1{}) returns true.
|
||||
/// </remarks>
|
||||
/// <param name="implementationType">Implementation type</param>
|
||||
/// <param name="serviceType">Service type</param>
|
||||
/// <returns>Whether the implementation type implements the service type</returns>
|
||||
public static bool Implements(this Type implementationType, Type serviceType)
|
||||
{
|
||||
return serviceType.IsAssignableFrom(implementationType) ||
|
||||
|
@ -41,22 +63,35 @@ namespace StyletIoC.Internal
|
|||
{ typeof(double), "double" },
|
||||
{ typeof(decimal), "decimal" },
|
||||
{ typeof(bool), "bool" },
|
||||
{ typeof(string), "string" },
|
||||
};
|
||||
|
||||
public static string Description(this Type type)
|
||||
/// <summary>
|
||||
/// Return a human-readable description of the given type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This returns things like 'List{int}' instead of 'List`1[System.Int32]'
|
||||
/// </remarks>
|
||||
/// <param name="type">Type to generate the description for</param>
|
||||
/// <returns>Description of the given type</returns>
|
||||
public static string GetDescription(this Type type)
|
||||
{
|
||||
if (type.IsGenericTypeDefinition)
|
||||
return String.Format("{0}<{1}>", type.Name.Split('`')[0], String.Join(", ", type.GetTypeInfo().GenericTypeParameters.Select(x => x.Name)));
|
||||
var genericArguments = type.GetGenericArguments();
|
||||
|
||||
string name;
|
||||
if (genericArguments.Length > 0)
|
||||
{
|
||||
return String.Format("{0}<{1}>", type.Name.Split('`')[0], String.Join(", ", genericArguments.Select(x =>
|
||||
{
|
||||
string name;
|
||||
return primitiveNameMapping.TryGetValue(x, out name) ? name : x.Name;
|
||||
})));
|
||||
}
|
||||
return type.Name;
|
||||
else
|
||||
{
|
||||
return primitiveNameMapping.TryGetValue(type, out name) ? name : type.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal.Creators;
|
||||
using StyletIoC.Internal.Registrations;
|
||||
using System;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using StyletIoC.Internal;
|
||||
using StyletIoC.Internal.Builders;
|
||||
using StyletIoC.Internal.Creators;
|
||||
using StyletIoC.Internal.Registrations;
|
||||
using System;
|
||||
|
@ -22,12 +23,6 @@ namespace StyletIoC
|
|||
/// <returns></returns>
|
||||
IInScopeOrWithKeyOrAsWeakBinding ToSelf();
|
||||
|
||||
/// <summary>
|
||||
/// Bind the specified service to another type which implements that service. E.g. builder.Bind{IMyClass}().To{MyClass}(), and request an IMyClass: you'll get a MyClass.
|
||||
/// </summary>
|
||||
/// <typeparam name="TImplementation">Type to bind the service to</typeparam>
|
||||
IInScopeOrWithKeyOrAsWeakBinding To<TImplementation>();
|
||||
|
||||
/// <summary>
|
||||
/// Bind the specified service to another type which implements that service. E.g. builder.Bind{IMyClass}().To(typeof(MyClass)), and request an IMyClass: you'll get a MyClass.
|
||||
/// </summary>
|
||||
|
@ -50,7 +45,7 @@ namespace StyletIoC
|
|||
/// Discover all implementations of the service in the specified assemblies / the current assembly, and bind those to the service
|
||||
/// </summary>
|
||||
/// <param name="assemblies">Assemblies to search. If empty / null, searches the current assembly</param>
|
||||
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(params Assembly[] assemblies);
|
||||
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -111,264 +106,6 @@ namespace StyletIoC
|
|||
IInScopeOrAsWeakBinding WithKey(string key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods providing scopes other than transitnet
|
||||
/// </summary>
|
||||
public static class StyletIoCScopeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Modify the scope of the binding to Singleton. One instance of this implementation will be generated for this binding.
|
||||
/// </summary>
|
||||
public static IAsWeakBinding InSingletonScope(this IInScopeOrAsWeakBinding builder)
|
||||
{
|
||||
return builder.WithRegistrationFactory((ctx, creator, key) => new SingletonRegistration(ctx, creator));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modify the scope binding to Per Container. One instance of this implementation will be generated per container / child container.
|
||||
/// </summary>
|
||||
public static IAsWeakBinding InPerContainerScope(this IInScopeOrAsWeakBinding builder)
|
||||
{
|
||||
return builder.WithRegistrationFactory((ctx, creator, key) => new PerContainerRegistration(ctx, creator, key));
|
||||
}
|
||||
}
|
||||
|
||||
internal class BuilderBindTo : IBindTo
|
||||
{
|
||||
public Type ServiceType { get; private set; }
|
||||
private BuilderBindingBase builderBinding;
|
||||
public bool IsWeak { get { return this.builderBinding.IsWeak; } }
|
||||
public string Key { get { return this.builderBinding.Key; } }
|
||||
|
||||
public BuilderBindTo(Type serviceType)
|
||||
{
|
||||
this.ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToSelf()
|
||||
{
|
||||
return this.To(this.ServiceType);
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding To<TImplementation>()
|
||||
{
|
||||
return this.To(typeof(TImplementation));
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding To(Type implementationType)
|
||||
{
|
||||
this.builderBinding = new BuilderTypeBinding(this.ServiceType, implementationType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToFactory<TImplementation>(Func<IRegistrationContext, TImplementation> factory)
|
||||
{
|
||||
this.builderBinding = new BuilderFactoryBinding<TImplementation>(this.ServiceType, factory);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IWithKey ToAbstractFactory()
|
||||
{
|
||||
this.builderBinding = new AbstractFactoryBinding(this.ServiceType);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(params Assembly[] assemblies)
|
||||
{
|
||||
if (assemblies == null || assemblies.Length == 0)
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
this.builderBinding = new BuilderToAllImplementationsBinding(this.ServiceType, assemblies);
|
||||
return this.builderBinding;
|
||||
}
|
||||
|
||||
internal void Build(Container container)
|
||||
{
|
||||
this.builderBinding.Build(container);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class BuilderBindingBase : IInScopeOrWithKeyOrAsWeakBinding, IWithKey
|
||||
{
|
||||
protected Type serviceType;
|
||||
protected RegistrationFactory registrationFactory;
|
||||
public string Key { get; protected set; }
|
||||
public bool IsWeak { get; protected set; }
|
||||
|
||||
public BuilderBindingBase(Type serviceType)
|
||||
{
|
||||
this.serviceType = serviceType;
|
||||
|
||||
// Default is transient
|
||||
this.registrationFactory = (ctx, creator, key) => new TransientRegistration(creator);
|
||||
}
|
||||
|
||||
IAsWeakBinding IInScopeOrAsWeakBinding.WithRegistrationFactory(RegistrationFactory registrationFactory)
|
||||
{
|
||||
if (registrationFactory == null)
|
||||
throw new ArgumentNullException("registrationFactory");
|
||||
this.registrationFactory = registrationFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
IInScopeOrAsWeakBinding IInScopeOrWithKeyOrAsWeakBinding.WithKey(string key)
|
||||
{
|
||||
this.Key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void EnsureType(Type implementationType, Type serviceType = null)
|
||||
{
|
||||
serviceType = serviceType ?? this.serviceType;
|
||||
|
||||
if (!implementationType.IsClass || implementationType.IsAbstract)
|
||||
throw new StyletIoCRegistrationException(String.Format("Type {0} is not a concrete class, and so can't be used to implemented service {1}", implementationType.Description(), serviceType.Description()));
|
||||
|
||||
// Test this first, as it's a bit clearer than hitting 'type doesn't implement service'
|
||||
if (implementationType.IsGenericTypeDefinition)
|
||||
{
|
||||
if (!serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("You can't use an unbound generic type to implement anything that isn't an unbound generic service. Service: {0}, Type: {1}", serviceType.Description(), implementationType.Description()));
|
||||
|
||||
// This restriction may change when I figure out how to pass down the correct type argument
|
||||
if (serviceType.GetTypeInfo().GenericTypeParameters.Length != implementationType.GetTypeInfo().GenericTypeParameters.Length)
|
||||
throw new StyletIoCRegistrationException(String.Format("If you're registering an unbound generic type to an unbound generic service, both service and type must have the same number of type parameters. Service: {0}, Type: {1}", serviceType.Description(), implementationType.Description()));
|
||||
}
|
||||
else if (serviceType.IsGenericTypeDefinition)
|
||||
{
|
||||
if (implementationType.GetGenericArguments().Length > 0)
|
||||
throw new StyletIoCRegistrationException(String.Format("You cannot bind the bound generic type {0} to the unbound generic service {1}", implementationType.Description(), serviceType.Description()));
|
||||
else
|
||||
throw new StyletIoCRegistrationException(String.Format("You cannot bind the non-generic type {0} to the unbound generic service {1}", implementationType.Description(), serviceType.Description()));
|
||||
}
|
||||
|
||||
if (!implementationType.Implements(this.serviceType))
|
||||
throw new StyletIoCRegistrationException(String.Format("Type {0} does not implement service {1}", implementationType.Description(), serviceType.Description()));
|
||||
}
|
||||
|
||||
// Convenience...
|
||||
protected void BindImplementationToService(Container container, Type implementationType, Type serviceType = null)
|
||||
{
|
||||
serviceType = serviceType ?? this.serviceType;
|
||||
|
||||
if (serviceType.IsGenericTypeDefinition)
|
||||
{
|
||||
var unboundGeneric = new UnboundGeneric(implementationType, container, this.registrationFactory);
|
||||
container.AddUnboundGeneric(new TypeKey(serviceType, this.Key), unboundGeneric);
|
||||
}
|
||||
else
|
||||
{
|
||||
var creator = new TypeCreator(implementationType, container);
|
||||
var registration = this.CreateRegistration(container, creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(serviceType, this.Key ?? creator.AttributeKey), registration);
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience...
|
||||
protected IRegistration CreateRegistration(IRegistrationContext registrationContext, ICreator creator)
|
||||
{
|
||||
return this.registrationFactory(registrationContext, creator, this.Key);
|
||||
}
|
||||
|
||||
void IWithKey.WithKey(string key)
|
||||
{
|
||||
this.Key = key;
|
||||
}
|
||||
|
||||
void IAsWeakBinding.AsWeakBinding()
|
||||
{
|
||||
this.IsWeak = true;
|
||||
}
|
||||
|
||||
public abstract void Build(Container container);
|
||||
}
|
||||
|
||||
internal class BuilderTypeBinding : BuilderBindingBase
|
||||
{
|
||||
private Type implementationType;
|
||||
|
||||
public BuilderTypeBinding(Type serviceType, Type implementationType) : base(serviceType)
|
||||
{
|
||||
this.EnsureType(implementationType);
|
||||
this.implementationType = implementationType;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
this.BindImplementationToService(container, this.implementationType);
|
||||
}
|
||||
}
|
||||
|
||||
internal class BuilderFactoryBinding<TImplementation> : BuilderBindingBase
|
||||
{
|
||||
private Func<IRegistrationContext, TImplementation> factory;
|
||||
|
||||
public BuilderFactoryBinding(Type serviceType, Func<IRegistrationContext, TImplementation> factory) : base(serviceType)
|
||||
{
|
||||
if (this.serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("A factory cannot be used to implement unbound generic type {0}", this.serviceType.Description()));
|
||||
this.EnsureType(typeof(TImplementation));
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var creator = new FactoryCreator<TImplementation>(this.factory, container);
|
||||
var registration = this.CreateRegistration(container, creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
|
||||
internal class BuilderToAllImplementationsBinding : BuilderBindingBase
|
||||
{
|
||||
private IEnumerable<Assembly> assemblies;
|
||||
|
||||
public BuilderToAllImplementationsBinding(Type serviceType, IEnumerable<Assembly> assemblies) : base(serviceType)
|
||||
{
|
||||
this.assemblies = assemblies;
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var candidates = from type in assemblies.Distinct().SelectMany(x => x.GetTypes())
|
||||
let baseType = type.GetBaseTypesAndInterfaces().FirstOrDefault(x => x == this.serviceType || x.IsGenericType && x.GetGenericTypeDefinition() == this.serviceType)
|
||||
where baseType != null
|
||||
select new { Type = type, Base = baseType.ContainsGenericParameters ? baseType.GetGenericTypeDefinition() : baseType };
|
||||
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.EnsureType(candidate.Type, candidate.Base);
|
||||
this.BindImplementationToService(container, candidate.Type, candidate.Base);
|
||||
}
|
||||
catch (StyletIoCRegistrationException e)
|
||||
{
|
||||
Debug.WriteLine(String.Format("Unable to auto-bind type {0} to {1}: {2}", candidate.Base.Name, candidate.Type.Description(), e.Message), "StyletIoC");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AbstractFactoryBinding : BuilderBindingBase
|
||||
{
|
||||
public AbstractFactoryBinding(Type serviceType) : base(serviceType)
|
||||
{
|
||||
if (serviceType.IsGenericTypeDefinition)
|
||||
throw new StyletIoCRegistrationException(String.Format("Unbound generic type {0} can't be used as an abstract factory", serviceType.Description()));
|
||||
}
|
||||
|
||||
public override void Build(Container container)
|
||||
{
|
||||
var factoryType = container.GetFactoryForType(this.serviceType);
|
||||
var creator = new AbstractFactoryCreator(factoryType);
|
||||
var registration = new TransientRegistration(creator);
|
||||
|
||||
container.AddRegistration(new TypeKey(this.serviceType, this.Key), registration);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This IStyletIoCBuilder is the only way to create an IContainer. Binding are registered using the builder, than an IContainer generated.
|
||||
/// </summary>
|
||||
|
@ -380,12 +117,6 @@ namespace StyletIoC
|
|||
/// <param name="serviceType">Service to bind</param>
|
||||
IBindTo Bind(Type serviceType);
|
||||
|
||||
/// <summary>
|
||||
/// Search the specified assembly(s) / the current assembly for concrete types, and self-bind them
|
||||
/// </summary>
|
||||
/// <param name="assemblies">Assembly(s) to search, or leave empty / null to search the current assembly</param>
|
||||
void Autobind(params Assembly[] assemblies);
|
||||
|
||||
/// <summary>
|
||||
/// Search the specified assembly(s) / the current assembly for concrete types, and self-bind them
|
||||
/// </summary>
|
||||
|
@ -448,18 +179,6 @@ namespace StyletIoC
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search the specified assembly(s) / the current assembly for concrete types, and self-bind them
|
||||
/// </summary>
|
||||
/// <param name="assemblies">Assembly(s) to search, or leave empty / null to search the current assembly</param>
|
||||
public void Autobind(params Assembly[] assemblies)
|
||||
{
|
||||
// Have to do null-or-empty check here as well, otherwise GetCallingAssembly returns this one....
|
||||
if (assemblies == null || assemblies.Length == 0)
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
this.Autobind(assemblies.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Once all bindings have been set, build an IContainer from which instances can be fetches
|
||||
/// </summary>
|
||||
|
@ -484,6 +203,19 @@ namespace StyletIoC
|
|||
/// </summary>
|
||||
public static class StyletIoCBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Search the specified assembly(s) / the current assembly for concrete types, and self-bind them
|
||||
/// </summary>
|
||||
/// <param name="builder">Builder to call on</param>
|
||||
/// <param name="assemblies">Assembly(s) to search, or leave empty / null to search the current assembly</param>
|
||||
public static void Autobind(this IStyletIoCBuilder builder, params Assembly[] assemblies)
|
||||
{
|
||||
// Have to do null-or-empty check here as well, otherwise GetCallingAssembly returns this one....
|
||||
if (assemblies == null || assemblies.Length == 0)
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
builder.Autobind(assemblies.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bind the specified service (interface, abstract class, concrete class, unbound generic, etc) to something
|
||||
/// </summary>
|
||||
|
@ -492,5 +224,43 @@ namespace StyletIoC
|
|||
{
|
||||
return builder.Bind(typeof(TService));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bind the specified service to another type which implements that service. E.g. builder.Bind{IMyClass}().To{MyClass}(), and request an IMyClass: you'll get a MyClass.
|
||||
/// </summary>
|
||||
/// <typeparam name="TImplementation">Type to bind the service to</typeparam>
|
||||
public static IInScopeOrWithKeyOrAsWeakBinding To<TImplementation>(this IBindTo bindTo)
|
||||
{
|
||||
return bindTo.To(typeof(TImplementation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discover all implementations of the service in the specified assemblies / the current assembly, and bind those to the service
|
||||
/// </summary>
|
||||
/// <param name="bindTo">Binder to call on</param>
|
||||
/// <param name="assemblies">Assemblies to search. If empty / null, searches the current assembly</param>
|
||||
public static IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(this IBindTo bindTo, params Assembly[] assemblies)
|
||||
{
|
||||
// Have to do null-or-empty check here as well, otherwise GetCallingAssembly returns this one....
|
||||
if (assemblies == null || assemblies.Length == 0)
|
||||
assemblies = new[] { Assembly.GetCallingAssembly() };
|
||||
return bindTo.ToAllImplementations(assemblies.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modify the scope of the binding to Singleton. One instance of this implementation will be generated for this binding.
|
||||
/// </summary>
|
||||
public static IAsWeakBinding InSingletonScope(this IInScopeOrAsWeakBinding builder)
|
||||
{
|
||||
return builder.WithRegistrationFactory((ctx, creator, key) => new SingletonRegistration(ctx, creator));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modify the scope binding to Per Container. One instance of this implementation will be generated per container / child container.
|
||||
/// </summary>
|
||||
public static IAsWeakBinding InPerContainerScope(this IInScopeOrAsWeakBinding builder)
|
||||
{
|
||||
return builder.WithRegistrationFactory((ctx, creator, key) => new PerContainerRegistration(ctx, creator, key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using NUnit.Framework;
|
||||
using StyletIoC;
|
||||
using StyletIoC.Builder;
|
||||
using StyletIoC.Creation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
Loading…
Reference in New Issue