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; } } }