using System; using Chernobyl.Collections.Generic.Event; namespace Chernobyl.Dependency { /// /// A class that can request a service, hold the service it receives, and /// invoke an event when that service is received. /// /// The type of the service to be retrieved from /// the class. public class Service { /// /// Initializes a new instance of the /// class. /// /// The instance that will provide the injection /// of the service. public Service(IEventCollection services) : this(services, Array.Empty) {} /// /// Initializes a new instance of the /// class. /// /// The instance that will provide the injection /// of the service. /// The location of the service as defined by /// . protected Service(IEventCollection services, params Type[] location) { _injectAttribute = new InjectAttribute(location) { Type = typeof (TService), SetValue = (obj, value, index) => Value = (TService) value }; _injectAttribute.Resolve(services, this, null); } /// /// An event that is raised right after this class has the service /// specified by (whose type is specified by /// ) set onto it. If the service /// has already been received, then any event handlers added to this /// event will be raised. /// public event EventHandler Received { add { _received += value; if (_serviceReceived == true) value(this, EventArgs.Empty); } remove { _received -= value; } } /// /// The service instance that is to be retrieved from the services /// instance passed to the constructor of this class. /// public TService Value { get { return _value; } set { _value = value; _serviceReceived = true; if (_received != null) _received(this, EventArgs.Empty); } } /// /// The backing method to . /// EventHandler _received; /// /// The backing field to . /// TService _value; /// /// True if the service has been received, false if otherwise. /// bool _serviceReceived; /// /// The which is used to handle the /// injection of the service. /// readonly InjectAttribute _injectAttribute; } /// /// Performs the exact same job as but this /// class allows you to specify an type to search for /// in. /// /// The type of the /// where is contained. /// The type of the service to be retrieved from /// the class. public class Service : Service where TServices : IEventCollection { /// /// Initializes a new instance of the /// class. /// /// The instance that will provide the injection /// of the service. public Service(IEventCollection services) : base(services, typeof(TServices)) { } } /// /// Performs the exact same job as /// but this class allows you to specify a two levels deep /// hierarchy to search in for /// . /// /// The type of the /// where is contained. /// The type of the /// where is contained. /// The type of the service to be retrieved from /// the class. public class Service : Service where TServices1 : IEventCollection where TServices2 : IEventCollection { /// /// Initializes a new instance of the /// class. /// /// The instance that will provide the injection /// of the service. public Service(IEventCollection services) : base(services, typeof(TServices1), typeof(TServices2)) { } } /// /// Performs the exact same job as /// but this class allows you to specify a three levels deep /// hierarchy to search in for /// . /// /// The type of the /// where is contained. /// The type of the /// where is contained. /// The type of the /// where is contained. /// The type of the service to be retrieved from /// the class. public class Service : Service where TServices1 : IEventCollection where TServices2 : IEventCollection where TServices3 : IEventCollection { /// /// Initializes a new instance of the /// class. /// /// The instance that will provide the injection /// of the service. public Service(IEventCollection services) : base(services, typeof(TServices1), typeof(TServices2), typeof(TServices3)) { } } }