Split out the type which were all previously in StyletIoCContainer.cs

This commit is contained in:
Antony Male 2014-07-21 10:57:18 +01:00
parent 95f0f8b3e4
commit 6533b34757
7 changed files with 240 additions and 195 deletions

View File

@ -58,6 +58,10 @@
<Compile Include="LambdaEqualityComparer.cs" />
<Compile Include="MessageBox.cs" />
<Compile Include="StyletConductorExtensions.cs" />
<Compile Include="StyletIoC\IInjectionAware.cs" />
<Compile Include="StyletIoC\InjectAttribute.cs" />
<Compile Include="StyletIoC\StyletIoCException.cs" />
<Compile Include="StyletIoC\TypeExtensions.cs" />
<Compile Include="ValidatingModelBase.cs" />
<Compile Include="Xaml\ActionExtension.cs" />
<Compile Include="AssemblySource.cs" />

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StyletIoC
{
/// <summary>
/// Describes an IoC container, specifically StyletIoC
/// </summary>
public interface IContainer
{
/// <summary>
/// Compile all known bindings (which would otherwise be compiled when needed), checking the dependency graph for consistency
/// </summary>
/// <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
/// </summary>
/// <param name="type">Type of service to fetch an implementation for</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>An instance of the requested service</returns>
object Get(Type type, string key = null);
/// <summary>
/// Fetch a single instance of the specified type
/// </summary>
/// <typeparam name="T">Type of service to fetch an implementation for</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>An instance of the requested service</returns>
T Get<T>(string key = null);
/// <summary>
/// Fetch instances of all types which implement the specified service
/// </summary>
/// <param name="type">Type of the service to fetch implementations for</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>All implementations of the requested service, with the requested key</returns>
IEnumerable<object> GetAll(Type type, string key = null);
/// <summary>
/// Fetch instances of all types which implement the specified service
/// </summary>
/// <typeparam name="T">Type of the service to fetch implementations for</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>All implementations of the requested service, with the requested key</returns>
IEnumerable<T> GetAll<T>(string key = null);
/// <summary>
/// If type is an IEnumerable{T} or similar, is equivalent to calling GetAll{T}. Else, is equivalent to calling Get{T}.
/// </summary>
/// <param name="type">If IEnumerable{T}, will fetch all implementations of T, otherwise wil fetch a single T</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns></returns>
object GetTypeOrAll(Type type, string key = null);
/// <summary>
/// If type is an IEnumerable{T} or similar, is equivalent to calling GetAll{T}. Else, is equivalent to calling Get{T}.
/// </summary>
/// <typeparam name="T">If IEnumerable{T}, will fetch all implementations of T, otherwise wil fetch a single T</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns></returns>
T GetTypeOrAll<T>(string key = null);
/// <summary>
/// For each property/field with the [Inject] attribute, sets it to an instance of that type
/// </summary>
/// <param name="item">Item to build up</param>
void BuildUp(object item);
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StyletIoC
{
/// <summary>
/// Interface to be implemented by objects if they want to be notified when property injection has occurred
/// </summary>
public interface IInjectionAware
{
/// <summary>
/// Called by StyletIoC when property injection has occurred
/// </summary>
void ParametersInjected();
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StyletIoC
{
/// <summary>
/// Attribute which can be used to mark the constructor to use, properties to inject, which key to use to resolve an injected property, and others. See the docs
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class InjectAttribute : Attribute
{
/// <summary>
/// Create a new InjectAttribute
/// </summary>
public InjectAttribute()
{
}
/// <summary>
/// Create a new InjectAttribute, which has the specified key
/// </summary>
/// <param name="key"></param>
public InjectAttribute(string key)
{
this.Key = key;
}
/// <summary>
/// Key to use to resolve the relevant dependency
/// </summary>
public string Key { get; set; }
}
}

View File

@ -12,72 +12,6 @@ using System.Threading.Tasks;
namespace StyletIoC
{
/// <summary>
/// Describes an IoC container, specifically StyletIoC
/// </summary>
public interface IContainer
{
/// <summary>
/// Compile all known bindings (which would otherwise be compiled when needed), checking the dependency graph for consistency
/// </summary>
/// <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
/// </summary>
/// <param name="type">Type of service to fetch an implementation for</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>An instance of the requested service</returns>
object Get(Type type, string key = null);
/// <summary>
/// Fetch a single instance of the specified type
/// </summary>
/// <typeparam name="T">Type of service to fetch an implementation for</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>An instance of the requested service</returns>
T Get<T>(string key = null);
/// <summary>
/// Fetch instances of all types which implement the specified service
/// </summary>
/// <param name="type">Type of the service to fetch implementations for</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>All implementations of the requested service, with the requested key</returns>
IEnumerable<object> GetAll(Type type, string key = null);
/// <summary>
/// Fetch instances of all types which implement the specified service
/// </summary>
/// <typeparam name="T">Type of the service to fetch implementations for</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns>All implementations of the requested service, with the requested key</returns>
IEnumerable<T> GetAll<T>(string key = null);
/// <summary>
/// If type is an IEnumerable{T} or similar, is equivalent to calling GetAll{T}. Else, is equivalent to calling Get{T}.
/// </summary>
/// <param name="type">If IEnumerable{T}, will fetch all implementations of T, otherwise wil fetch a single T</param>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns></returns>
object GetTypeOrAll(Type type, string key = null);
/// <summary>
/// If type is an IEnumerable{T} or similar, is equivalent to calling GetAll{T}. Else, is equivalent to calling Get{T}.
/// </summary>
/// <typeparam name="T">If IEnumerable{T}, will fetch all implementations of T, otherwise wil fetch a single T</typeparam>
/// <param name="key">Key that implementations of the service to fetch were registered with, defaults to null</param>
/// <returns></returns>
T GetTypeOrAll<T>(string key = null);
/// <summary>
/// For each property/field with the [Inject] attribute, sets it to an instance of that type
/// </summary>
/// <param name="item">Item to build up</param>
void BuildUp(object item);
}
/// <summary>
/// Lightweight, very fast IoC container
/// </summary>
@ -559,133 +493,4 @@ namespace StyletIoC
return other != null && this.Type == other.Type && this.Key == other.Key;
}
}
internal static class TypeExtensions
{
public static IEnumerable<Type> GetBaseTypesAndInterfaces(this Type type)
{
return type.GetInterfaces().Concat(type.GetBaseTypes());
}
public static IEnumerable<Type> GetBaseTypes(this Type type)
{
for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType)
{
yield return baseType;
}
}
public static bool Implements(this Type implementationType, Type serviceType)
{
return serviceType.IsAssignableFrom(implementationType) ||
implementationType.GetBaseTypesAndInterfaces().Any(x => x == serviceType || (x.IsGenericType && x.GetGenericTypeDefinition() == serviceType));
}
private static readonly Dictionary<Type, string> primitiveNameMapping = new Dictionary<Type, string>()
{
{ typeof(byte), "byte" },
{ typeof(sbyte), "sbyte" },
{ typeof(char), "char" },
{ typeof(short), "short" },
{ typeof(ushort), "ushort" },
{ typeof(int), "int" },
{ typeof(uint), "uint" },
{ typeof(long), "long" },
{ typeof(ulong), "ulong" },
{ typeof(float), "float" },
{ typeof(double), "double" },
{ typeof(decimal), "decimal" },
{ typeof(bool), "bool" },
};
public static string Description(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();
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;
}
}
/// <summary>
/// Interface to be implemented by objects if they want to be notified when property injection has occurred
/// </summary>
public interface IInjectionAware
{
/// <summary>
/// Called by StyletIoC when property injection has occurred
/// </summary>
void ParametersInjected();
}
/// <summary>
/// Base class for all exceptions describing StyletIoC-specific problems?
/// </summary>
public abstract class StyletIoCException : Exception
{
internal StyletIoCException(string message) : base(message) { }
internal StyletIoCException(string message, Exception innerException) : base(message, innerException) { }
}
/// <summary>
/// A problem occured with a registration process (failed to register, failed to find a registration, etc)
/// </summary>
public class StyletIoCRegistrationException : StyletIoCException
{
internal StyletIoCRegistrationException(string message) : base(message) { }
internal StyletIoCRegistrationException(string message, Exception innerException) : base(message, innerException) { }
}
/// <summary>
/// StyletIoC was unable to find a callable constructor for a type
/// </summary>
public class StyletIoCFindConstructorException : StyletIoCException
{
internal StyletIoCFindConstructorException(string message) : base(message) { }
}
/// <summary>
/// StyletIoC was unable to create an abstract factory
/// </summary>
public class StyletIoCCreateFactoryException : StyletIoCException
{
internal StyletIoCCreateFactoryException(string message) : base(message) { }
internal StyletIoCCreateFactoryException(string message, Exception innerException) : base(message, innerException) { }
}
/// <summary>
/// Attribute which can be used to mark the constructor to use, properties to inject, which key to use to resolve an injected property, and others. See the docs
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class InjectAttribute : Attribute
{
/// <summary>
/// Create a new InjectAttribute
/// </summary>
public InjectAttribute()
{
}
/// <summary>
/// Create a new InjectAttribute, which has the specified key
/// </summary>
/// <param name="key"></param>
public InjectAttribute(string key)
{
this.Key = key;
}
/// <summary>
/// Key to use to resolve the relevant dependency
/// </summary>
public string Key { get; set; }
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StyletIoC
{
/// <summary>
/// Base class for all exceptions describing StyletIoC-specific problems?
/// </summary>
public abstract class StyletIoCException : Exception
{
internal StyletIoCException(string message) : base(message) { }
internal StyletIoCException(string message, Exception innerException) : base(message, innerException) { }
}
/// <summary>
/// A problem occured with a registration process (failed to register, failed to find a registration, etc)
/// </summary>
public class StyletIoCRegistrationException : StyletIoCException
{
internal StyletIoCRegistrationException(string message) : base(message) { }
internal StyletIoCRegistrationException(string message, Exception innerException) : base(message, innerException) { }
}
/// <summary>
/// StyletIoC was unable to find a callable constructor for a type
/// </summary>
public class StyletIoCFindConstructorException : StyletIoCException
{
internal StyletIoCFindConstructorException(string message) : base(message) { }
}
/// <summary>
/// StyletIoC was unable to create an abstract factory
/// </summary>
public class StyletIoCCreateFactoryException : StyletIoCException
{
internal StyletIoCCreateFactoryException(string message) : base(message) { }
internal StyletIoCCreateFactoryException(string message, Exception innerException) : base(message, innerException) { }
}
}

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace StyletIoC
{
internal static class TypeExtensions
{
public static IEnumerable<Type> GetBaseTypesAndInterfaces(this Type type)
{
return type.GetInterfaces().Concat(type.GetBaseTypes());
}
public static IEnumerable<Type> GetBaseTypes(this Type type)
{
for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType)
{
yield return baseType;
}
}
public static bool Implements(this Type implementationType, Type serviceType)
{
return serviceType.IsAssignableFrom(implementationType) ||
implementationType.GetBaseTypesAndInterfaces().Any(x => x == serviceType || (x.IsGenericType && x.GetGenericTypeDefinition() == serviceType));
}
private static readonly Dictionary<Type, string> primitiveNameMapping = new Dictionary<Type, string>()
{
{ typeof(byte), "byte" },
{ typeof(sbyte), "sbyte" },
{ typeof(char), "char" },
{ typeof(short), "short" },
{ typeof(ushort), "ushort" },
{ typeof(int), "int" },
{ typeof(uint), "uint" },
{ typeof(long), "long" },
{ typeof(ulong), "ulong" },
{ typeof(float), "float" },
{ typeof(double), "double" },
{ typeof(decimal), "decimal" },
{ typeof(bool), "bool" },
};
public static string Description(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();
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;
}
}
}