Search code examples
c#inversion-of-controldecoratorsimple-injector

Register Decorator in Simple injector, common interface


I have a problem with a IoC with Simple Injector for Decorator..

How to register it in the Ioc Simple injector ?

var data = new Data();
var test = new Data2Decorator (data,
    new Data1Decorator(data, new XxxData(data)))

I tried it this way.

_container.Register<Ixxx1>();
_container.Register<Ixxx2>();
_container.Register<Ixxx, Data>();
_container.Register<IData, XxxData>();
container.RegisterDecorator<IData, Data1Decorator>();
_container.RegisterDecorator<IData, Data2Decorator>():          
public interface Ixxx1
{
    public IEnumerable<...> x1 { get; set; }
}
public class Data1Decorator : DataDecorator
{
    public readonly Ixxx1 _xxx1; 

    public Data1Decorator(Ixxx1 xxx1, IData data) : base(data)
    {
        _xxx1 = xxx1;
    }

    public override Task Load()
    {
        return Task.WhenAll(new List<Task>() { ..., base.Load() })
        .ContinueWith((b) =>
        { 
               _xxx1.x1 = ...
        });
    }
}

Common storage Data

public interface Ixxx :
    Ixxx1,
    Ixxx2
{

}

public class Data: Ixxx
{ 
    public IEnumerable<...> x1 { get; set; }

    public IEnumerable<...> x2 { get; set; }
}

Solution

  • _container.Register<Ixxx, Data>();
    _container.Register<IData<Ixxx>, XxxData>();
    _container.RegisterDecorator<IData<Ixxx>, Data1Decorator<Ixxx>>();
    _container.RegisterDecorator<IData<Ixxx>, Data2Decorator<Ixxx>>():
    
        public interface IData<out TData>
        {
            TData Data { get; }
            Task Load();
        }
    
        public abstract class DataDecorator<TData> : IData<TData>
        {
            public readonly IData<TData> _data;
    
            public TData Data => _data.Data;
    
            protected DataDecorator(IData<TData> data) => _data = data;
    
            public virtual Task Load() => _data.Load();
        }
    
        public interface Ixxx :
            Ixxx1,
            Ixxx2
        {
    
        }
    
        public class XxxData : IData<Ixxx>
        {
            public Ixxx Data { get; }
    
            public XxxData(Ixxx data) => Data = data;
    
            public Task Load() => Task.Run(() => { });
        }
    
        public interface Ixxx1
        {
            public IEnumerable<...> x1 { get; set; }
        }
    
        public class Data1Decorator<TData> : DataDecorator<TData>
            where TData : Ixxx1
        {
    
            public Data1Decorator(IData data) : base(data)
            {
            }
    
            public override Task Load()
            {
                return Task.WhenAll(new List<Task>() { ..., base.Load() })
                .ContinueWith((b) =>
                { 
                       Data.x1 = ...
                });
            }
        }