using System; using Chernobyl.Utility; using Chernobyl.Values; namespace Chernobyl.Conversion { /// /// Converts a value contained within an /// to and from another value and maintains that conversion. /// /// The first type to be converted to and from. /// The second type to be converted to and from. public class TwoWayConversion : FromSourceConversion, IDynamicContainer { /// /// Initializes a new instance of the class. /// /// The instance whose contained value is to be /// converted. /// The method that performs the conversion of /// to . /// The method that performs the conversion of /// to . public TwoWayConversion(IDynamicContainer container, Func oneToTwo, Func twoToOne) : base(container, oneToTwo) { container.ThrowIfNull("container"); _container = container; twoToOne.ThrowIfNull("twoToOne"); _twoToOne = twoToOne; } /// /// The value held by this instance. If the value has not yet been /// provided it will be equal to default(T). /// public new T2 Value { get { return base.Value; } set { // The base class will update the contained value when the // _container is updated. _container.Value = _twoToOne(value); } } /// /// The method that performs the conversion of /// to . /// readonly Func _twoToOne; /// /// The instance whose contained value is to be converted. /// readonly IDynamicContainer _container; } /// /// Utility and extensions methods for /// and its dependencies. /// public static class TwoWayConversionExtensions { /// /// Returns an that holds and /// maintains a conversion to and from another . /// /// The first type to be converted to and from. /// The second type to be converted to and from. /// The instance whose contained value is to be /// converted. /// The method that performs the conversion of /// to . /// The method that performs the conversion of /// to . /// The which holds and /// maintains the conversion. public static IDynamicContainer Convert( this IDynamicContainer container, Func oneToTwo, Func twoToOne) { return new TwoWayConversion(container, oneToTwo, twoToOne); } } }