using System;
using System.Collections.Generic;
using System.Linq;
using EcsRx.Collections;
using EcsRx.Groups;
using EcsRx.Groups.Observable;
using EcsRx.Infrastructure.Dependencies;
using EcsRx.Systems;
namespace EcsRx.Infrastructure.Extensions
{
public static class IDependencyContainerExtensions
{
///
/// Binds from one type to another, generally from an interface to a concrete class
///
/// The container to bind on
/// Optional configuration
/// Type to bind from
/// Type to bind to
public static void Bind(this IDependencyContainer container, BindingConfiguration configuration = null) where TTo : TFrom
{ container.Bind(typeof(TFrom), typeof(TTo), configuration); }
///
/// Binds from one type to another, generally from an interface to a concrete class
///
/// The container to bind on
/// Optional configuration
/// Source and possible destination binding, i.e concrete class
/// This is useful for self binding concrete classes
public static void Bind(this IDependencyContainer container, BindingConfiguration configuration = null)
{ container.Bind(typeof(T), configuration); }
///
/// Bind using a builder for fluent configuration
///
/// container to act on
/// configuration handler
/// Type to bind to
public static void Bind(this IDependencyContainer container, Action> builderAction)
{
var builder = new BindingBuilder();
builderAction(builder);
var config = builder.Build();
container.Bind(config);
}
///
/// Bind using a builder for fluent configuration
///
/// container to act on
/// configuration handler
/// Type to bind from
/// Type to bind to
public static void Bind(this IDependencyContainer container, Action builderAction) where TTo : TFrom
{
var builder = new BindingBuilder();
builderAction(builder);
var config = builder.Build();
container.Bind(config);
}
///
/// Checks to see if a binding exists in the container
///
/// The container to check against
/// Optional name of the binding
/// Type to check against
/// True if the type has been bound, false if not
public static bool HasBinding(this IDependencyContainer container, string name = null)
{ return container.HasBinding(typeof(T), name); }
///
/// Gets an instance of a given type from the underlying DI container
///
/// The container to resolve from
/// Optional name of the binding
/// Type of the object you want
/// An instance of the given type
public static T Resolve(this IDependencyContainer container, string name = null)
{ return (T)container.Resolve(typeof(T), name); }
///
/// Unbinds a type from the container
///
/// The type to unbind
public static void Unbind(this IDependencyContainer container)
{ container.Unbind(typeof(T)); }
///
/// Gets an enumerable of a given type from the underlying DI container
///
/// Type to resolve
/// All matching instances of that type within the underlying container
public static IEnumerable ResolveAll(this IDependencyContainer container)
{ return container.ResolveAll(typeof(T)).Cast(); }
///
/// Loads the given modules bindings into the underlying di container
///
/// Type of module to load
public static void LoadModule(this IDependencyContainer container) where T : IDependencyModule, new()
{ container.LoadModule(new T()); }
///
/// Resolves an observable group
///
/// The container to action on
/// The group to observe
/// The observable group
public static IObservableGroup ResolveObservableGroup(this IDependencyContainer container, IGroup group)
{
var collectionManager = container.Resolve();
return collectionManager.GetObservableGroup(group);
}
///
/// Resolves an observable group
///
/// The container to action on
/// The required components for the group to observe
///
public static IObservableGroup ResolveObservableGroup(this IDependencyContainer container, params Type[] componentTypes)
{
var collectionManager = container.Resolve();
var group = new Group(componentTypes);
return collectionManager.GetObservableGroup(group);
}
public static void BindApplicableSystems(this IDependencyContainer container, params string[] namespaces)
{
var applicationAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var systemType = typeof(ISystem);
var applicableSystems = applicationAssemblies.SelectMany(x => x.GetTypes())
.Where(x =>
{
if (x.IsInterface || x.IsAbstract)
{ return false; }
if (string.IsNullOrEmpty(x.Namespace))
{ return false; }
if (!systemType.IsAssignableFrom(x))
{ return false; }
return namespaces.Any(namespaceToVerify => x.Namespace == namespaceToVerify);
})
.ToList();
foreach (var applicableSystemType in applicableSystems)
{
var bindingConfiguration = new BindingConfiguration
{
AsSingleton = true,
WithName = applicableSystemType.FullName
};
container.Bind(typeof(ISystem), applicableSystemType, bindingConfiguration);
}
}
public static void UnbindApplicableSystems(this IDependencyContainer container, params string[] namespaces)
{
var applicationAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var systemType = typeof(ISystem);
var applicableSystems = applicationAssemblies.SelectMany(x => x.GetTypes())
.Where(x =>
{
if (x.IsInterface || x.IsAbstract)
{ return false; }
if (string.IsNullOrEmpty(x.Namespace))
{ return false; }
if (!systemType.IsAssignableFrom(x))
{ return false; }
return namespaces.Any(namespaceToVerify => x.Namespace == namespaceToVerify);
})
.ToList();
foreach (var applicableSystemType in applicableSystems)
{
container.UnbindId(typeof(ISystem), applicableSystemType, applicableSystemType.FullName);
}
}
public static List ResolveApplicableSystems(this IDependencyContainer container, params string[] namespaces)
{
List systems = new List();
var applicationAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var systemType = typeof(ISystem);
var applicableSystems = applicationAssemblies.SelectMany(x => x.GetTypes())
.Where(x =>
{
if (x.IsInterface || x.IsAbstract)
{ return false; }
if (string.IsNullOrEmpty(x.Namespace))
{ return false; }
if (!systemType.IsAssignableFrom(x))
{ return false; }
return namespaces.Any(namespaceToVerify => x.Namespace == namespaceToVerify);
})
.ToList();
foreach (var applicableSystemType in applicableSystems)
{
systems.Add(container.Resolve(typeof(ISystem), applicableSystemType.FullName) as ISystem);
}
return systems;
}
}
}