public void FindGenericBaseType_ThrowsAnExceptionForNullType() { // Arrange var type = (Type)null; // Act and assert var exception = Assert.Throws <ArgumentNullException>(() => BpmNetCoreHelpers.FindGenericBaseType(type, type)); Assert.Equal("type", exception.ParamName); }
public void FindGenericBaseType_NullDefinitionType() { // Arrange var type = typeof(ICustom4 <,>); var definition = typeof(ICustomInterface <>); // Act and assert var generic = BpmNetCoreHelpers.FindGenericBaseType(type, definition); Assert.Null(generic); }
public void FindGenericBaseType_InterfaceDefinitionType() { // Arrange var type = typeof(ICustom3 <,>); var definition = typeof(ICustomInterface <>); // Act and assert var generic = BpmNetCoreHelpers.FindGenericBaseType(type, definition); Assert.Equal(typeof(ICustomInterface <BpmNetCoreOptions>), generic); }
public void FindGenericBaseType_ThrowsAnExceptionForNullDefinition() { // Arrange var type = typeof(string); var definition = (Type)null; // Act and assert var exception = Assert.Throws <ArgumentNullException>(() => BpmNetCoreHelpers.FindGenericBaseType(type, definition)); Assert.Equal("definition", exception.ParamName); }
public void FindGenericBaseType_ThrowsAnExceptionForNonGenericType() { // Arrange var type = typeof(string); var definition = typeof(string); // Act and assert var exception = Assert.Throws <ArgumentException>(() => BpmNetCoreHelpers.FindGenericBaseType(type, definition)); Assert.Equal("definition", exception.ParamName); Assert.StartsWith("The second parameter must be a generic type definition.", exception.Message); }
/// <summary> /// Replace the default definition service by a custom service derived /// from <see cref="BpmNetDefinitionService{TDefinition}"/>. /// Note: when using this overload, the definition service can be /// either a non-generic, a closed or an open generic service. /// </summary> /// <param name="type">The type of the custom service.</param> /// <param name="lifetime">The lifetime of the registered service.</param> /// <returns>The <see cref="BpmNetCoreBuilder"/>.</returns> public BpmNetCoreBuilder ReplaceDefinitionService(Type type, ServiceLifetime lifetime = ServiceLifetime.Singleton) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var root = BpmNetCoreHelpers.FindGenericBaseType(type, typeof(BpmNetDefinitionService <,>)); if (root == null) { throw new ArgumentException("The specified type is invalid.", nameof(type)); } // Note: service can be either open generics (e.g BpmNetDefinitionService<,>) // or closed generics (e.g BpmNetDefinitionService<BpmNetDefinition>). if (type.IsGenericTypeDefinition) { if (type.GetGenericArguments().Length != 2) { throw new ArgumentException("The specified type is invalid.", nameof(type)); } Services.Replace(new ServiceDescriptor(type, type, lifetime)); Services.Replace(new ServiceDescriptor(typeof(BpmNetDefinitionService <,>), type, lifetime)); } else { object ResolveService(IServiceProvider provider) => provider.GetRequiredService(typeof(BpmNetDefinitionService <,>) .MakeGenericType(root.GenericTypeArguments[0], root.GenericTypeArguments[1])); Services.Replace(new ServiceDescriptor(type, ResolveService, lifetime)); Services.Replace(new ServiceDescriptor(typeof(BpmNetDefinitionService <,>) .MakeGenericType(root.GenericTypeArguments[0], root.GenericTypeArguments[1]), type, lifetime)); } return(this); }
public IBpmNetProcessInstanceStore <TInstance, TInstanceFlow> GetProcessInstanceStore <TInstance, TInstanceFlow>() where TInstance : class, IProcessInstance <TInstanceFlow> where TInstanceFlow : class, IBpmNetInstanceFlow { var store = _provider.GetService <IBpmNetProcessInstanceStore <TInstance, TInstanceFlow> >(); if (store != null) { return(store); } var type = _cache.GetOrAdd(typeof(TInstance), key => { var root = BpmNetCoreHelpers.FindGenericBaseType(key, typeof(BpmNetProcessInstance <>)); if (root == null) { throw new InvalidOperationException(new StringBuilder() .AppendLine("The specified start event type is not compatible with the Entity Framework Core stores. ") .Append("When enabling the Entity Framework Core stores, make sure your entity is Assignable From ") .Append("'IBpmNetProcess' in your entity model (from the 'BpmNet.Abstractions' package) ") .Append("or a custom entity that inherits from the generic 'BpmNetProcessInstance' entity.") .ToString()); } var context = _options.CurrentValue.DbContextType; if (context == null) { throw new InvalidOperationException(new StringBuilder() .AppendLine("No Entity Framework Core context was specified in the BpmNet options. ") .Append("To configure the BpmNet Entity Framework Core stores to use a specific 'DbContext', ") .Append("use 'options.UseEntityFrameworkCore().UseDbContext<TContext>()'.") .ToString()); } return(typeof(BpmNetProcessInstanceStore <, ,>).MakeGenericType(context, key, root.GenericTypeArguments[0])); }); return((IBpmNetProcessInstanceStore <TInstance, TInstanceFlow>)_provider.GetRequiredService(type)); }