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