Beispiel #1
0
        public static IEnumerator <ResolutionStepResult> InstantiationCoroutine(object activationScope, IDIContainer container)
        {
            // Hack to allow IDataProvider to resolve on time
            // (we allow other widgets to be resolved and register the dependency required, while this one is in waiting state)
            return(ResolutionStepResult.WAITING_FOR_SERVICE
                   .Repeat(1) // skip specified amount of steps
                   .Concat(Helpers.CoroutineEnumerable(instantiate))
                   .GetEnumerator());

            void instantiate()
            {
                var dr = new DeviceDataRequestVM(
                    container.ResolveSingle <IRUSDevice>(),
                    container.ResolveSingle <BusyObject>(),
#warning will not return all providers if at the time of resolving not all of them were registered
                    container.TryResolveAll <IDataProvider>()?.ToArray() ?? new IDataProvider[0]);
                var widget = new DataRequest()
                {
                    Model = new DataRequestVM(container.ResolveSingle <IRUSDevice>(),
                                              dr,
                                              new DeviceDataAutorequestVM(dr.GetDataRequest, container.ResolveSingle <BusyObject>())),
                    FunctionId = new WidgetIdentity("Опрос",
                                                    container.ResolveSingle <string>(),
                                                    activationScope)
                };

                container.Register <IWidget>(widget);
                container.Register <IDeviceHandler>(widget.Model);
                container.Register <IDataStorageVM>(widget.Model.RequestVM.DeviceDataVM, activationScope);
                container.Register <IPointsStorageProvider>(widget.Model.RequestVM.DeviceDataVM, activationScope);
            }
        }
        public virtual IEnumerable <T> TryResolveAll <T>(object scope = null) where T : class
        {
            throwIfDisposed();

            return(_base.TryResolveAll <T>(scope));
        }
        public override void ExecuteCoroutines(IEnumerator <ResolutionStepResult>[] coroutines)
        {
            var widgets = new List <IWidget> [coroutines.Length];

            widgets.SetAll(() => new List <IWidget>());

            for (int i = 0; i < coroutines.Length; i++)
            {
                var unwrapped = coroutines[i];
                coroutines[i] = wrap(i, unwrapped);
            }

            base.ExecuteCoroutines(coroutines);

            reregisterInCorrectOrder();

            IEnumerator <ResolutionStepResult> wrap(int coroutineIndex, IEnumerator <ResolutionStepResult> coroutine)
            {
                var old = getAllWidgets();

                while (coroutine.MoveNext())
                {
                    var current = getAllWidgets();
                    var delta   = current.Where(w => !old.Contains(w)).ToArray();

                    switch (coroutine.Current)
                    {
                    case ResolutionStepResult.WAITING_FOR_SERVICE:
                        break;

                    case ResolutionStepResult.RESOLVED:
                        widgets[coroutineIndex].AddRange(delta);
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    yield return(coroutine.Current);

                    old = getAllWidgets();
                }

                IEnumerable <IWidget> getAllWidgets()
                {
                    return(_container.TryResolveAll <IWidget>()?.ToArray() ?? new IWidget[0]);
                }
            }

            void reregisterInCorrectOrder()
            {
                var distinctWidgets = new HashSet <IWidget>();

                foreach (var coroutineWidgets in widgets)
                {
                    foreach (var widget in coroutineWidgets.Distinct())
                    {
                        distinctWidgets.Add(widget);
                    }
                }

                _container.RemoveRegistration <IWidget>();
                foreach (var widget in distinctWidgets)
                {
                    _container.Register <IWidget>(widget);
                }
            }
        }