public void AddOrUpdateImplementation <TInterface, TImplementation, TCollectionChangeInterceptor>() where TInterface : IEnumerable where TImplementation : class, TInterface where TCollectionChangeInterceptor : class { Type interfaceType = typeof(TInterface).GetTypeInfo().GetGenericTypeDefinition(); Type implementationType = typeof(TImplementation).GetTypeInfo().GetGenericTypeDefinition(); Type collectionChangeInterceptorType = typeof(TCollectionChangeInterceptor).GetTypeInfo().GetGenericTypeDefinition(); Contract.Requires(() => interfaceType.GetTypeInfo().IsInterface, $"Given type in generic parameter '{nameof(TInterface)}' must be an interface"); lock (_syncLock) { Implementations[interfaceType] = new CollectionImplementation(implementationType, collectionChangeInterceptorType); } }
/// <summary> /// Replaces an existing collection interface/implementation or adds it. /// </summary> /// <param name="interfaceType"></param> /// <param name="implementationType"></param> /// <param name="collectionChangeInterceptor">An implementation to interface type which intercepts calls to the whole collection type to handle changes</param> public void ReplaceImplementation(Type interfaceType, Type implementationType, Type collectionChangeInterceptor) { Contract.Requires(interfaceType != null, "Cannot add an implementation of a null interface"); Contract.Requires(interfaceType.IsInterface, "Given type must be an interface"); Contract.Requires(interfaceType.IsGenericTypeDefinition, "Given collection interface must be provided as a generic type definition"); Contract.Requires(interfaceType.IsAssignableFrom(collectionChangeInterceptor), "Provided change interceptor type must be assignable to collection implementation type"); lock (_syncLock) { if (Implementations.ContainsKey(interfaceType)) { Implementations[interfaceType] = new CollectionImplementation(implementationType, collectionChangeInterceptor); } else { AddImplementation(interfaceType, implementationType, collectionChangeInterceptor); } } }