[英]How to use Reflection in factory design patterns in C# .Net core
I've implementing the Factory Method in c#.Net core in the following way.I have several concrete products let's say Gateway1
and Gateway2
我通过以下方式在 c#.Net 核心中实现了工厂方法。我有几个具体的产品,比如Gateway1
和Gateway2
public interface IGateway
{
void Test();
}
ConcreteCreator:具体创建者:
public class PaymentFactory
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
private readonly IPaymentGatewayRepository _paymentGatewayRepository;
public PaymentFactory(IPaymentTransactionRepository paymentTransactionRepository,
IPaymentGatewayRepository paymentGatewayRepository)
{
_paymentTransactionRepository = paymentTransactionRepository;
_paymentGatewayRepository = paymentGatewayRepository;
}
public IGateway ExecuteCreation(string bank)
{
switch (bank)
{
case "Gateway1":
{
return new Gateway1(_paymentGatewayRepository);
}
case "Gateway2":
{
return new Gateway2(_paymentTransactionRepository, _paymentGatewayRepository);
}
default:
{
return null;
}
}
}
}
ConcreteProducts:具体产品:
public class Gateway1 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
public Gateway1(IPaymentTransactionRepository paymentGatewayRepository)
{
_paymentGatewayRepository = paymentGatewayRepository;
}
public void Test()
{
//code
}
}
public class Gateway2 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
private readonly IPaymentGatewayRepository _paymentGatewayRepository;
public Gateway2(IPaymentTransactionRepository paymentGatewayRepository,
IPaymentGatewayRepository paymentGatewayRepository)
{
_paymentGatewayRepository = paymentGatewayRepository;
_paymentGatewayRepository = paymentGatewayRepository;
}
public void Test()
{
//code
}
}
This code is running but I want to make two changes to it.此代码正在运行,但我想对其进行两处更改。
1- How to implementing the Factory Method by Reflection? 1- 如何通过反射实现工厂方法?
2- How to pass in multiple parameters to Create ConcreteProducts
? 2-如何将多个参数传递给 Create ConcreteProducts
?
Thanks in advance.提前致谢。
you can use bellow code.You need to change the PaymentFactory
as follows.您可以使用波纹管代码。您需要按如下方式更改PaymentFactory
。 you can user IServiceProvider Injection of the service into the constructor of the class where it's used.您可以使用IServiceProvider将服务注入到使用它的类的构造函数中。
ConcreteProducts Names:混凝土产品名称:
public enum PaymentGatewayEnum
{
Gateway1 = 1,
Gateway2 = 2,
}
then PaymentFactory:然后支付工厂:
public class PaymentFactory
{
private readonly IServiceProvider _serviceProvider;
public PaymentFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IGateway ExecuteCreation(PaymentGatewayEnum bank)
{
var services = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
.Where(x => typeof(IGateway).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
.FirstOrDefault(x => string.Equals(x.Name, bank.ToString(), StringComparison.CurrentCultureIgnoreCase));
return Activator.CreateInstance(services, _serviceProvider) as IGateway;
}
}
and then:进而:
public class Gateway1 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
public Gateway1(IServiceProvider serviceProvider)
{
_paymentTransactionRepository = (IPaymentTransactionRepository)serviceProvider.GetService(typeof(IPaymentTransactionRepository));
}
public void Test()
{
//code
}
}
public class Gateway2 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
private readonly IPaymentGatewayRepository _paymentGatewayRepository;
public Gateway2(IServiceProvider serviceProvider)
{
_paymentTransactionRepository = (IPaymentTransactionRepository)serviceProvider.GetService(typeof(IPaymentTransactionRepository));
_paymentGatewayRepository = (IPaymentGatewayRepository)serviceProvider.GetService(typeof(IPaymentGatewayRepository));
}
public void Test()
{
//code
}
}
An alternative to Reza Jenabi's solution is the following: Reza Jenabi 解决方案的替代方案如下:
Enum to select between gateways:在网关之间枚举到 select:
public enum PaymentGatewayType
{
GATEWAY1,
GATEWAY2,
}
The factory interface:工厂界面:
public interface IPaymentFactory
{
}
The factory, which can be registered as a singleton:工厂,可注册为singleton:
public class PaymentFactory : IPaymentFactory
{
private Dictionary<PaymentGatewayType, Func<IGateway>> GatewayTypes
= new Dictionary<PaymentGatewayType, Func<IGateway>>();
public PaymentFactory(IServiceProvider serviceProvider)
{
Gateways = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => typeof(IGateway).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
.Select(t => new Func<IGateway>(() =>
ActivatorUtilities.CreateInstance(serviceProvider, t) as IGateway))
.ToDictionary(f => f().GatewayType);
}
public IGateway GetGateway(PaymentGatewayType gatewayType)
{
return GatewayTypes[gatewayType]();
}
}
The gateways:网关:
public interface IGateway
{
//The GatewayType property is important as that's what the PaymentFactory uses
// as a discriminator (see .ToDictionary(f => f().GatewayType);)
PaymentGatewayType GatewayType{ get; }
void Test();
}
public class Gateway1 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
//Here we override the GatewayType property in the interface to set which
//gateway this class belongs to
public override PaymentGatewayType GatewayType => PaymentGatewayType.GATEWAY1;
public Gateway1(IPaymentTransactionRepository paymentGatewayRepository)
{
_paymentGatewayRepository = paymentGatewayRepository;
}
public void Test()
{
//code
}
}
public class Gateway2 : IGateway
{
private readonly IPaymentTransactionRepository _paymentTransactionRepository;
private readonly IPaymentGatewayRepository _paymentGatewayRepository;
//Here we override the GatewayType property in the interface to set which
//gateway this class belongs to
public override PaymentGatewayType GatewayType => PaymentGatewayType.GATEWAY2;
public Gateway2(IPaymentTransactionRepository paymentGatewayRepository,
IPaymentGatewayRepository paymentGatewayRepository)
{
_paymentGatewayRepository = paymentGatewayRepository;
_paymentGatewayRepository = paymentGatewayRepository;
}
public void Test()
{
//code
}
}
Then in the calling code something like the following:然后在调用代码中如下所示:
public class GatewayService
{
private readonly IPaymentFactory _paymentFactory;
public GatewayService(IPaymentFactory paymentFactory)
{
_paymentFactory = paymentFactory;
}
public void DoSomething(PaymentGatewayType gatewayType)
{
IGateway gateway = _paymentFactory.GetGateway(gatewayType);
gateway.Test();
}
}
To add more Gateways simply add a new enum Value, eg GATEWAY3 and create a new Gateway3 class that inherits from IGateway.要添加更多网关,只需添加一个新的枚举值,例如 GATEWAY3,并创建一个继承自 IGateway 的新网关 3 class。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.