private static void IServiceContainerConformanceAddRemove(ISimpleServiceContainer container, Func <IAddService> creatorFunc) { container.GetService <IAddService>().Should().BeNull("Starting with no IAddService."); container.Add(creatorFunc); container.Invoking(sut => sut.Add(creatorFunc)).Should().Throw <Exception>("Adding an already existing service throws an exception."); container.GetService <IAddService>().Should().NotBeNull("Deferred creation occured."); container.Remove(typeof(IAddService)); container.GetService <IAddService>().Should().BeNull("Remove works."); // Removing an unexisting service is okay. container.Remove(typeof(IAddService)); bool removed = false; container.Add <IAddService>(creatorFunc, s => removed = true); container.Remove(typeof(IAddService)); removed.Should().BeFalse("Since the service has never been required, it has not been created, hence, OnRemove action has not been called."); container.Add <IAddService>(creatorFunc, s => removed = true); container.GetService <IAddService>().Should().NotBeNull("Service has been created."); container.Remove(typeof(IAddService)); removed.Should().BeTrue("This time, OnRemove action has been called."); removed = false; container.Add <IAddService>(new AddServiceImpl(), s => removed = true); container.Remove(typeof(IAddService)); removed.Should().BeTrue("Since the service instance has been added explicitely, OnRemove action has been called."); }
/// <summary> /// Type safe version to register a service associated to a callback. /// The <paramref name="serviceInstance"/> is called as long as no service has been obtained (serviceInstance returns null). /// Once the actual service has been obtained, it is kept and serviceInstance is not called anymore. /// </summary> /// <param name="this">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Delegate to call when needed. Can not be null.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer @this, Func <T> serviceInstance) where T : class { // It is the overloaded version that takes a Func<object> serviceInstance // that is called (unit tests asserts this). // To allow the covariance, we MUST constrain the type T to be a reference class (hence the where clause). return(@this.Add(typeof(T), serviceInstance, null)); }
private static void IServiceContainerConformanceAddRemove(ISimpleServiceContainer container, Func <IAddService> creatorFunc) { Assert.That(container.GetService <IAddService>() == null, "Starting with no IAddService."); container.Add <IAddService>(creatorFunc); Assert.Throws <CKException>(() => container.Add <IAddService>(creatorFunc), "Adding an already existing service throws an exception."); Assert.That(container.GetService <IAddService>() != null, "Deferred creation occured."); container.Remove(typeof(IAddService)); Assert.That(container.GetService <IAddService>() == null, "Remove works."); // Removing an unexisting service is okay. container.Remove(typeof(IAddService)); bool removed = false; container.Add <IAddService>(creatorFunc, s => removed = true); container.Remove(typeof(IAddService)); Assert.That(removed == false, "Since the service has never been required, it has not been created, hence, OnRemove action has not been called."); container.Add <IAddService>(creatorFunc, s => removed = true); Assert.That(container.GetService <IAddService>() != null, "Service has been created."); container.Remove(typeof(IAddService)); Assert.That(removed, "This time, OnRemove action has been called."); removed = false; container.Add <IAddService>(new AddServiceImpl(), s => removed = true); container.Remove(typeof(IAddService)); Assert.That(removed, "Since the service instance has been added explicitely, OnRemove action has been called."); }
/// <summary> /// Type safe version to register a service implementation (type of the service is the type of the implementation), /// and a callback that will be called when the service is eventually removed. /// </summary> /// <param name="this">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Implementation of the service. Can not be null.</param> /// <param name="onRemove">Action that will be called whenever <see cref="ISimpleServiceContainer.Remove"/>, <see cref="ISimpleServiceContainer.Clear"/> or <see cref="IDisposable.Dispose"/>.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer @this, T serviceInstance, Action <T> onRemove) { if (onRemove == null) { throw new ArgumentNullException(nameof(onRemove)); } return(@this.Add(typeof(T), serviceInstance, o => onRemove((T)o))); }
private static void IServiceContainerConformanceRemoveRecursive(ISimpleServiceContainer container) { bool removedCall = false; container.Add <IAddService>(new AddServiceImpl(), s => { removedCall = true; container.Remove(typeof(IAddService)); }); Assert.That(container.GetService <IAddService>(), Is.Not.Null); container.Remove(typeof(IAddService)); Assert.That(removedCall, "OnRemove has been called and can safely remove the service again without stack overflow exception."); }
private static void IServiceContainerConformanceRemoveRecursive(ISimpleServiceContainer container) { bool removedCall = false; container.Add <IAddService>(new AddServiceImpl(), s => { removedCall = true; container.Remove(typeof(IAddService)); }); container.GetService <IAddService>(false).Should().NotBeNull(); container.Remove(typeof(IAddService)); removedCall.Should().BeTrue("OnRemove has been called and can safely remove the service again without stack overflow exception."); }
/// <summary> /// Tests the fact that the ISimpleServiceContainer set as parameter is conform to the way the interface should be used. /// </summary> /// <typeparam name="T">the service implemented by the servicecontainer's baseprovider </typeparam> /// <param name="container">the ISimpleServiceContainer implementation to test</param> /// <param name="baseProviderServiceToTest"></param> public void IServiceContainerConformanceTest <T>(ISimpleServiceContainer container, ISimpleServiceContainer baseProvider, T baseProviderServiceToTest) { Func <IAddService> creatorFunc = () => new AddServiceImpl(); IServiceContainerCoAndContravariance(container, creatorFunc); IServiceContainerConformanceAddRemove(container, creatorFunc); IServiceContainerConformanceAddFailsWhenExisting(container, creatorFunc); IServiceContainerConformanceRemoveRecursive(container); container.Add <IAddService>(creatorFunc); container.Add <ISubstractService>(new SubstractServiceImpl()); IAddService service = container.GetService <IAddService>(); Assert.That(service != null); Assert.That(service.GetType(), Is.EqualTo(typeof(AddServiceImpl))); Assert.That(service.Add(1, 1), Is.EqualTo(2)); ISubstractService substractService = container.GetService <ISubstractService>(); Assert.That(substractService != null); Assert.That(substractService.GetType(), Is.EqualTo(typeof(SubstractServiceImpl))); Assert.That(substractService.Substract(1, 1), Is.EqualTo(0)); //clear test container.Clear(); Assert.That(container.GetService <IAddService>(), Is.Null); Assert.That(container.GetService <ISubstractService>(), Is.Null); //base provider test if (baseProvider != null && baseProviderServiceToTest != null) { T baseService = container.GetService <T>(); Assert.That(baseService != null, "The baseProvider contains the specified service."); container.Remove(typeof(T)); baseService = container.GetService <T>(); Assert.That(baseService != null, "Trying to remove a base service from a child provider does nothing."); container.AddDisabled(typeof(T)); Assert.That(container.GetService <T>(), Is.Null, "Access to this service is disabled"); baseProvider.Remove(typeof(T)); Assert.That(container.GetService <T>(), Is.Null, "Access to this service is disabled & The service doesn't exist anymore on the baseProvider"); container.Remove(typeof(T)); Assert.That(container.GetService <T>(), Is.Null, "The service doesn't exist anymore on the baseProvider"); baseProvider.Add(baseProviderServiceToTest); Assert.That(container.GetService <T>(), Is.Not.Null, "Back to the beginning's state, the service is retrieved from the base provider."); } }
public SharedDictionaryImpl(IServiceProvider serviceProvider) { _serviceContainer = new SimpleServiceContainer(serviceProvider); _serviceContainer.Add <ISimpleTypeFinder>(SimpleTypeFinder.WeakDefault); _fragments = new Dictionary <object, List <SkippedFragment> >(); _values = new Dictionary <SharedDictionaryEntry, SharedDictionaryEntry>(); _byObject = new Dictionary <object, PluginConfigByObject>(); _byPlugin = new Dictionary <Guid, PluginConfigByPlugin>(); _finalDictionary = new Dictionary <SharedDictionaryEntry, FinalDictionary>(_comparerForFinalDictionaryMap); }
private static void IServiceContainerConformanceAddFailsWhenExisting(ISimpleServiceContainer container, Func <IAddService> creatorFunc) { container.Add <IAddService>(new AddServiceImpl()); Assert.Throws <CKException>(() => container.Add(creatorFunc)); Assert.Throws <CKException>(() => container.Add <IAddService>(creatorFunc, s => { })); Assert.Throws <CKException>(() => container.Add(typeof(IAddService), new AddServiceImpl())); Assert.Throws <CKException>(() => container.Add(typeof(IAddService), new AddServiceImpl(), s => { })); Assert.Throws <CKException>(() => container.Add <IAddService>(new AddServiceImpl())); Assert.Throws <CKException>(() => container.Add <IAddService>(new AddServiceImpl(), s => { })); Assert.Throws <CKException>(() => container.AddDisabled(typeof(IAddService))); container.Remove(typeof(IAddService)); }
private static void IServiceContainerConformanceAddFailsWhenExisting(ISimpleServiceContainer container, Func <IAddService> creatorFunc) { container.Add <IAddService>(new AddServiceImpl()); container.Invoking(sut => sut.Add(creatorFunc)).Should().Throw <Exception>(); container.Invoking(sut => sut.Add <IAddService>(creatorFunc, s => { })).Should().Throw <Exception>(); container.Invoking(sut => sut.Add(typeof(IAddService), new AddServiceImpl())).Should().Throw <Exception>(); container.Invoking(sut => sut.Add(typeof(IAddService), new AddServiceImpl(), s => { })).Should().Throw <Exception>(); container.Invoking(sut => sut.Add <IAddService>(new AddServiceImpl())).Should().Throw <Exception>(); container.Invoking(sut => sut.Add <IAddService>(new AddServiceImpl(), s => { })).Should().Throw <Exception>(); container.Invoking(sut => sut.AddDisabled(typeof(IAddService))).Should().Throw <Exception>(); container.Remove(typeof(IAddService)); }
/// <summary> /// Initializes a new plugin manager. /// </summary> /// <param name="registry">The registry of plugins.</param> /// <param name="baseProvider">The base service provider.</param> /// <param name="commandRegister">Command registerer.</param> /// <param name="defaultBranchName">The default branch name (typically "develop"). Must not be null or empty.</param> public GitPluginManager(GitPluginRegistry registry, ISimpleServiceContainer baseProvider, CommandRegister commandRegister, string defaultBranchName) { if (String.IsNullOrWhiteSpace(defaultBranchName)) { throw new ArgumentNullException(nameof(defaultBranchName)); } ServiceContainer = new SimpleServiceContainer(baseProvider); _defaultBranchName = defaultBranchName; _commandRegister = commandRegister ?? throw new ArgumentNullException(nameof(commandRegister)); Registry = registry; _plugins = new PluginCollection <IGitPlugin>(this, null); _branches = new Branches(this); }
/// <summary> /// Type safe version to register a service associated to a callback (and a callback that will be called when the service is eventually removed). /// The <paramref name="serviceInstance"/> is called as long as no service has been obtained (serviceInstance returns null). /// Once the actual service has been obtained, it is kept and serviceInstance is not called anymore. /// </summary> /// <param name="this">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Delegate to call when needed. Can not be null.</param> /// <param name="onRemove">Action that will be called whenever <see cref="ISimpleServiceContainer.Remove"/>, <see cref="ISimpleServiceContainer.Clear"/> or <see cref="IDisposable.Dispose"/> /// is called and a service as been successfuly obtained.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer @this, Func <T> serviceInstance, Action <T> onRemove) where T : class { // It is the overloaded version that takes a Func<object> serviceInstance // that is called (unit tests asserts this). // To allow the covariance, we MUST constrain the type T to be a reference class (hence the where clause). // // On the other hand, for the onRemove action we can not do any miracle: we need to adapt the call. // if (onRemove == null) { throw new ArgumentNullException(nameof(onRemove)); } return(@this.Add(typeof(T), serviceInstance, o => onRemove((T)o))); }
private static void IServiceContainerCoAndContravariance(ISimpleServiceContainer container, Func <IAddService> creatorFunc) { { _onRemoveServiceCalled = false; container.Add <IAddService>(new AddServiceImpl(), OnRemoveService); container.Remove(typeof(IAddService)); Assert.That(_onRemoveServiceCalled, "OnRemoveService has been called."); _onRemoveServiceCalled = false; container.Add <IAddService>(new AddServiceImpl(), OnRemoveBaseServiceType); container.Remove(typeof(IAddService)); Assert.That(_onRemoveServiceCalled, "OnRemoveBaseServiceType has been called."); _onRemoveServiceCalled = false; container.Add <IAddService>(new AddServiceImpl(), OnRemoveServiceObject); container.Remove(typeof(IAddService)); Assert.That(_onRemoveServiceCalled, "OnRemoveServiceObject has been called."); //container.Add<IAddService>( new AddServiceImpl(), OnRemoveDerivedServiceType ); //container.Remove( typeof( IAddService ) ); //container.Add<IAddService>( new AddServiceImpl(), OnRemoveUnrelatedType ); //container.Remove( typeof( IAddService ) ); } { _onRemoveServiceCalled = false; container.Add(creatorFunc, OnRemoveService); container.Remove(typeof(IAddService)); Assert.That(!_onRemoveServiceCalled, "Service has never been created."); container.Add <IAddService>(creatorFunc, OnRemoveBaseServiceType); container.Remove(typeof(IAddService)); Assert.That(!_onRemoveServiceCalled, "Service has never been created."); container.Add <IAddService>(creatorFunc, OnRemoveServiceObject); container.Remove(typeof(IAddService)); Assert.That(!_onRemoveServiceCalled, "Service has never been created."); } }
/// <summary> /// Type safe version to register a service implementation (type of the service is the type of the implementation). /// </summary> /// <param name="c">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Implementation of the service. Can not be null.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer c, T serviceInstance) { c.Add(typeof(T), serviceInstance, null); return(c); }
/// <summary> /// Gets whether a service is available. /// (This simply calls <see cref="IServiceProvider.GetService(Type)"/> and checks for a non null value.) /// </summary> /// <param name="this">This container.</param> /// <param name="serviceType">Service type.</param> /// <returns>True if the service is available, false otherwise.</returns> public static bool IsAvailable(this ISimpleServiceContainer @this, Type serviceType) => @this.GetService(serviceType) != null;
/// <summary> /// Gets whether a service is available. /// (This simply calls <see cref="IServiceProvider.GetService(Type)"/> and checks for a non null value.) /// </summary> /// <typeparam name="T">Type of the service.</typeparam> /// <param name="this">This container.</param> /// <returns>True if the service is available, false otherwise.</returns> public static bool IsAvailable <T>(this ISimpleServiceContainer @this) => IsAvailable(@this, typeof(T));
/// <summary> /// Type safe version to remove a registered type. /// </summary> /// <param name="this">This <see cref="ISimpleServiceContainer"/> object.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Remove <T>(this ISimpleServiceContainer @this) { return(@this.Remove(typeof(T))); }
/// <summary> /// Type safe version to register a service implementation (type of the service is the type of the implementation). /// </summary> /// <param name="this">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Implementation of the service. Can not be null.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer @this, T serviceInstance) { return(@this.Add(typeof(T), serviceInstance, null)); }
/// <summary> /// Tests the fact that the ISimpleServiceContainer set as parameter is conform to the way the interface should be used. /// </summary> /// <param name="container">the ISimpleServiceContainer implementation to test</param> public void IServiceContainerConformanceTest(ISimpleServiceContainer container) { IServiceContainerConformanceTest <object>(container, null, null); }
public Context(ISimpleServiceContainer c) { _container = c; }
/// <summary> /// Type safe version to register a service implementation (type of the service is the type of the implementation), /// and an optional callback that will be called when the service will be removed. /// </summary> /// <param name="c">This <see cref="ISimpleServiceContainer"/> object.</param> /// <param name="serviceInstance">Implementation of the service. Can not be null.</param> /// <param name="onRemove">Optional action that will be called whenever <see cref="ISimpleServiceContainer.Remove"/>, <see cref="ISimpleServiceContainer.Clear"/> or <see cref="IDisposable.Dispose"/>.</param> /// <returns>This object to enable fluent syntax.</returns> public static ISimpleServiceContainer Add <T>(this ISimpleServiceContainer c, T serviceInstance, Action <T> onRemove) { c.Add(typeof(T), serviceInstance, o => onRemove((T)o)); return(c); }