public void AddAdapter_Works() { var services = new ServiceCollection(); services.TryAddScoped <TestService>(); services.TryAddSingleton <MapperConfiguration>(fact => new MapperConfiguration(cfg => cfg.CreateMap <CustomTestType, TestType>().ReverseMap())); services.TryAddScoped <DefaultAdapterMapper>(fact => { var mapperConfig = fact.GetRequiredService <MapperConfiguration>(); var mapper = new DefaultAdapterMapper(mapperConfig.CreateMapper()); return(mapper); }); services.AddAdapter <ICustomTestService <CustomTestType>, TestService>(targetFact => targetFact.GetRequiredService <TestService>(), (serviceProvider, target) => { var mapper = serviceProvider.GetRequiredService <DefaultAdapterMapper>(); var interceptor = new AdapterInterceptor <TestService, CustomTestType, TestType>(target, mapper, TestHelper.LoggerFactory); return(interceptor); }, ServiceLifetime.Scoped); var provider = services.BuildServiceProvider(); var service = provider.GetRequiredService <ICustomTestService <CustomTestType> >(); var result = service.MethodUsingOneArgument(new CustomTestType()); Assert.IsNotNull(result); }
public static IServiceCollection AddScopedBlogServiceAdapter <T>(this IServiceCollection services) { services.AddScoped <SqliteConnection>(fact => { var tmp = new SqliteConnection("DataSource=:memory:"); return(tmp); }); services.AddScoped <BlogContext>(fact => { // This connection is explicitly provided so we have to manage it explicitly by // opening, closing and disposing it var connection = fact.GetService <SqliteConnection>(); // Provided by logger frameworks as a singleton var loggerFactory = fact.GetService <ILoggerFactory>(); var options = new DbContextOptionsBuilder <BlogContext>() .UseSqlite(connection) .UseLoggerFactory(loggerFactory) .Options; var context = new BlogContext(options); // In-memory database exists only for the duration of an open connection context.Database.OpenConnection(); context.Database.EnsureCreated(); return(context); }); services.AddScoped <BlogService>(); // Register the adapter // The IBlogServiceAdapter interface inherits the IDisposable interface. When the scope is closed, the adapter instance will be disposed of by the DI framework, which will also invoke the Dispose() method on the target through the AdapterInterceptor. Note we have to release the AdapterInterceptor to release the target, it is never released by the Dispose() method invocation services.AddAdapter <IBlogServiceAdapter <T>, BlogService>(targetFact => { // Obtain the target - the adaptee var blogService = targetFact.GetService <BlogService>(); return(blogService); }, (serviceProvider, target) => { var mapperConfiguration = serviceProvider.GetService <MapperConfiguration>(); var adapterMapper = new DefaultAdapterMapper(mapperConfiguration.CreateMapper()); #if DEBUG // AdapterInterceptor emits logs when TRACE logger level is enabled for com.github.akovac35.AdapterInterceptor. This can be quite verbose but enables method invocation diagnostics. It is possible to completely disable logging by simply not providing a logger factory var loggerFactory = serviceProvider.GetService <ILoggerFactory>(); var adapterInterceptor = new CustomAdapterInterceptor <BlogService, Blog, T>(target, adapterMapper, loggerFactory); #else var adapterInterceptor = new CustomAdapterInterceptor <BlogService, Blog, T>(target, adapterMapper); #endif return(adapterInterceptor); }, ServiceLifetime.Scoped); return(services); }
public void GenerateAdapter_Works() { var service = new TestService(); var mapperConfig = new MapperConfiguration(cfg => cfg.CreateMap <CustomTestType, TestType>().ReverseMap()); var mapper = new DefaultAdapterMapper(mapperConfig.CreateMapper()); var adapter = service.GenerateAdapter <ICustomTestService <CustomTestType>, TestService>(target => new AdapterInterceptor <TestService, CustomTestType, TestType>(target, mapper)); var result = adapter.MethodUsingOneArgument(new CustomTestType()); Assert.IsNotNull(result); adapter = service.GenerateAdapter <ICustomTestService <CustomTestType>, TestService>(target => new AdapterInterceptor <TestService, CustomTestType, TestType>(target, mapper, TestHelper.LoggerFactory)); result = adapter.MethodUsingOneArgument(new CustomTestType()); Assert.IsNotNull(result); }
public void Map_ForSimpleTypes_Works() { var source = new TestType(); var sourceType = typeof(TestType); var destinationType = typeof(CustomTestType); var mapperConfiguration = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, destinationType)); var mapper = mapperConfiguration.CreateMapper(); var adapterMapper = new DefaultAdapterMapper(mapper); var destination = adapterMapper.Map(source, sourceType, destinationType) as CustomTestType; Assert.IsNotNull(destination); Assert.IsTrue(source.Name == destination.Name); Assert.IsTrue(source.Value == destination.Value); }
public void Map_ForCollections_Works() { var source = new List <TestType>(); source.Add(new TestType()); var sourceType = typeof(TestType); var sourceTypeCollection = typeof(List <TestType>); var destinationType = typeof(CustomTestType); var destinationTypeCollection = typeof(List <CustomTestType>); var mapperConfiguration = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, destinationType)); var mapper = mapperConfiguration.CreateMapper(); var adapterMapper = new DefaultAdapterMapper(mapper); var destination = adapterMapper.Map(source, sourceTypeCollection, destinationTypeCollection) as List <CustomTestType>; Assert.IsNotNull(destination); Assert.IsTrue(destination.Count == 1); Assert.IsTrue(source[0].Name == destination[0].Name); Assert.IsTrue(source[0].Value == destination[0].Value); }
public static IContainer CreateContainerBuilder() { var builder = new ContainerBuilder(); // Services builder.RegisterType <TestService>(); // AutoMapper builder.RegisterInstance(new MapperConfiguration(cfg => { // Just add a few mappings which will not actually be used IEnumerable <Type> builtInPrimitiveTypes = typeof(int).Assembly.GetTypes().Where(t => t.IsPrimitive); var supportedTypePairs = from source in builtInPrimitiveTypes from destination in builtInPrimitiveTypes where source != destination select new TypePair(source, destination); supportedTypePairs = supportedTypePairs.GroupBy(item => item.SourceType).Select(group => group.First()); foreach (var item in supportedTypePairs) { cfg.CreateMap(item.SourceType, item.DestinationType); } cfg.CreateMap <CustomTestType, TestType>().ReverseMap(); })).Named <MapperConfiguration>("ComplexMapperConfig"); builder.RegisterInstance(new MapperConfiguration(cfg => cfg.CreateMap <CustomTestType, TestType>().ReverseMap())).Named <MapperConfiguration>("SimpleMapperConfig"); // Default builder.RegisterInstance(new MapperConfiguration(cfg => cfg.CreateMap <CustomTestType, TestType>().ReverseMap())).AsSelf(); builder.Register(ctx => ctx.ResolveNamed <MapperConfiguration>("ComplexMapperConfig").CreateMapper()).Named <IMapper>("ComplexMapper"); builder.Register(ctx => ctx.ResolveNamed <MapperConfiguration>("SimpleMapperConfig").CreateMapper()).Named <IMapper>("SimpleMapper"); // Default builder.Register(ctx => ctx.Resolve <MapperConfiguration>().CreateMapper()).As <IMapper>(); // IAdapterMapper builder.Register(ctx => { var mapper = ctx.ResolveNamed <IMapper>("ComplexMapper"); var adapterMapper = new DefaultAdapterMapper(mapper); return(adapterMapper); }).Named <DefaultAdapterMapper>("ComplexDefaultAdapterMapperForBenchmarks"); builder.Register(ctx => { var mapper = ctx.ResolveNamed <IMapper>("SimpleMapper"); var adapterMapper = new DefaultAdapterMapper(mapper); return(adapterMapper); }).Named <DefaultAdapterMapper>("SimpleDefaultAdapterMapperForBenchmarks");; // Default builder.Register(ctx => { var mapper = ctx.Resolve <IMapper>(); var adapterMapper = new DefaultAdapterMapper(mapper); return(adapterMapper); }).As <IAdapterMapper>().As <DefaultAdapterMapper>(); // AdapterInterceptor builder.Register(ctx => { var mapper = ctx.ResolveNamed <IMapper>("ComplexMapper"); var adapterMapper = ctx.ResolveNamed <DefaultAdapterMapper>("ComplexDefaultAdapterMapperForBenchmarks"); var target = ctx.Resolve <TestService>(); // Must not use logging for benchmark return(new AdapterInterceptor <TestService>(target, adapterMapper, mapper.InitializeSupportedPairsFromMapper(), new ConcurrentDictionary <MethodInfo, AdapterInvocationInformation>())); }).Named <AdapterInterceptor <TestService> >("ComplexAdapterInterceptorForBenchmarks"); builder.Register(ctx => { var mapper = ctx.ResolveNamed <IMapper>("SimpleMapper"); var adapterMapper = ctx.ResolveNamed <DefaultAdapterMapper>("SimpleDefaultAdapterMapperForBenchmarks"); var target = ctx.Resolve <TestService>(); // Must not use logging for benchmark return(new AdapterInterceptor <TestService>(target, adapterMapper, mapper.InitializeSupportedPairsFromMapper(), new ConcurrentDictionary <MethodInfo, AdapterInvocationInformation>())); }).Named <AdapterInterceptor <TestService> >("SimpleAdapterInterceptorForBenchmarks"); // Default builder.Register(ctx => { var mapper = ctx.Resolve <IMapper>(); var adapterMapper = ctx.Resolve <DefaultAdapterMapper>(); var target = ctx.Resolve <TestService>(); return(new AdapterInterceptor <TestService>(target, adapterMapper, mapper.InitializeSupportedPairsFromMapper(), new ConcurrentDictionary <MethodInfo, AdapterInvocationInformation>(), TestHelper.LoggerFactory)); }).AsSelf(); // Generics builder.Register(ctx => { var adapterMapper = ctx.Resolve <IAdapterMapper>(); var target = ctx.Resolve <TestService>(); // Must not use logging for concurrency test return(new AdapterInterceptor <TestService, TestType, CustomTestType>(target, adapterMapper)); }).Named <AdapterInterceptor <TestService> >("GenericAdapterInterceptor"); // Proxies builder.RegisterInstance(new ProxyGenerator(true)).AsSelf(); builder.Register(ctx => { var adapterInterceptor = ctx.ResolveNamed <AdapterInterceptor <TestService> >("ComplexAdapterInterceptorForBenchmarks"); var proxyGen = ctx.Resolve <ProxyGenerator>(); return(proxyGen.CreateInterfaceProxyWithoutTarget <ICustomTestService <CustomTestType> >(adapterInterceptor)); }).Named <ICustomTestService <CustomTestType> >("ComplexCustomTestServiceForBenchmarks"); builder.Register(ctx => { var adapterInterceptor = ctx.ResolveNamed <AdapterInterceptor <TestService> >("SimpleAdapterInterceptorForBenchmarks"); var proxyGen = ctx.Resolve <ProxyGenerator>(); return(proxyGen.CreateInterfaceProxyWithoutTarget <ICustomTestService <CustomTestType> >(adapterInterceptor)); }).Named <ICustomTestService <CustomTestType> >("SimpleCustomTestServiceForBenchmarks"); // Default builder.Register(ctx => { var adapterInterceptor = ctx.Resolve <AdapterInterceptor <TestService> >(); var proxyGen = ctx.Resolve <ProxyGenerator>(); return(proxyGen.CreateInterfaceProxyWithoutTarget <ICustomTestService <CustomTestType> >(adapterInterceptor)); }).As <ICustomTestService <CustomTestType> >(); // Generic builder.Register(ctx => { var adapterInterceptor = ctx.ResolveNamed <AdapterInterceptor <TestService> >("GenericAdapterInterceptor"); var proxyGen = ctx.Resolve <ProxyGenerator>(); return(proxyGen.CreateInterfaceProxyWithoutTarget <ICustomTestService <CustomTestType> >(adapterInterceptor)); }).Named <ICustomTestService <CustomTestType> >("GenericCustomTestService"); return(builder.Build()); }