Created
March 13, 2019 21:31
-
-
Save pizycki/f2768236c450d12a405896112e170eed to your computer and use it in GitHub Desktop.
MSDI alternative for Autofac service resolving with parameter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using Microsoft.Extensions.DependencyInjection; | |
| using Xunit; | |
| namespace InjectDependencyWithProperty.src | |
| { | |
| public class UsersStorage | |
| { | |
| public void Create(object user) | |
| { | |
| // do nothing | |
| } | |
| } | |
| public class ServiceContext // Service Fabric | |
| { | |
| public T GetRemotingService<T>() => Activator.CreateInstance<T>(); | |
| } | |
| // Can turn into delegate | |
| public interface ICreateUserServiceFactory | |
| { | |
| ICreateUserService Create(ServiceContext serviceContext); | |
| } | |
| //public class CreateUserServiceFactory : ICreateUserServiceFactory | |
| //{ | |
| // private readonly IServiceProvider _serviceProvider; | |
| // public CreateUserServiceFactory(IServiceProvider serviceProvider) | |
| // { | |
| // _serviceProvider = serviceProvider; | |
| // } | |
| // public ICreateUserService Create(ServiceContext dependency) | |
| // { | |
| // var createUserService = _serviceProvider.GetService<CreateUserService>(); | |
| // var contextInjectable = (IDependencyViaProperty<ServiceContext>)createUserService; | |
| // contextInjectable.Dependency = dependency; | |
| // return createUserService; | |
| // } | |
| //} | |
| public class CreateUserServiceFactory : ICreateUserServiceFactory | |
| { | |
| private readonly GenericPropertyInjectionFactory<ICreateUserService, CreateUserService, ServiceContext> _factory; | |
| public CreateUserServiceFactory(GenericPropertyInjectionFactory<ICreateUserService, CreateUserService, ServiceContext> factory) | |
| { | |
| _factory = factory; | |
| } | |
| public ICreateUserService Create(ServiceContext serviceContext) => _factory.Create(serviceContext); | |
| } | |
| public class GenericPropertyInjectionFactory<TContract, TImplementation, TDependency> | |
| where TImplementation : TContract, IDependencyViaProperty<TDependency> | |
| { | |
| private readonly IServiceProvider _serviceProvider; | |
| public GenericPropertyInjectionFactory(IServiceProvider serviceProvider) | |
| { | |
| _serviceProvider = serviceProvider; | |
| } | |
| public TContract Create(TDependency dependency) | |
| { | |
| if (dependency == null) throw new ArgumentNullException(nameof(dependency)); | |
| var serviceInstance = _serviceProvider.GetService<TImplementation>(); | |
| var dependencyInjectable = (IDependencyViaProperty<TDependency>)serviceInstance; | |
| dependencyInjectable.Dependency = dependency; | |
| return serviceInstance; | |
| } | |
| } | |
| public interface ICreateUserService | |
| { | |
| // Contract remains clear | |
| void CreateUser(string userName); | |
| } | |
| public interface IDependencyViaProperty<in T> | |
| { | |
| /// <summary> | |
| /// Dependency injection point. Use instead of injecting via constructor. | |
| /// </summary> | |
| /// <exception cref="InvalidOperationException">Thrown when instance of Service Context has been already assigned in the instance.</exception> | |
| T Dependency { set; } | |
| } | |
| public class CreateUserService : ICreateUserService, IDependencyViaProperty<ServiceContext> | |
| { | |
| private ServiceContext _serviceContext; | |
| ServiceContext IDependencyViaProperty<ServiceContext>.Dependency | |
| { | |
| set | |
| { | |
| _serviceContext = _serviceContext == null | |
| ? value | |
| : throw new InvalidOperationException("Service Context already injected!"); | |
| } | |
| } | |
| public void CreateUser(string userName) | |
| { | |
| var storage = _serviceContext.GetRemotingService<UsersStorage>(); | |
| storage.Create(new | |
| { | |
| Name = userName | |
| }); | |
| } | |
| } | |
| public class Runner | |
| { | |
| [Fact] | |
| public void Main() | |
| { | |
| var services = new ServiceCollection(); | |
| services.AddTransient<CreateUserService>(); | |
| services.AddTransient(typeof(GenericPropertyInjectionFactory<,,>)); | |
| services.AddTransient<ICreateUserServiceFactory, CreateUserServiceFactory>(); | |
| var provider = services.BuildServiceProvider(); | |
| var createUserServiceFactory = provider.GetService<ICreateUserServiceFactory>(); | |
| var serviceFabricContext = new ServiceContext(); | |
| var createUserService = createUserServiceFactory.Create(serviceFabricContext); | |
| createUserService.CreateUser("Paweł Iżycki"); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment