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))
{ }
}
}