Why constrain to interface in generic typing? - c#

What would be the point of making a constraint for an interface type on a generic in C#? For example,
public interface IHandler<in T>
where T : IProcessor
{
void Handle(T command);
}
Wouldn't it be better to simply inherit IProcessor as a generic without any constraints? What is the advantage of doing it this way?
For example,
public class FooProcessor : IProcessor<T>
{
void Handle(T command)
{
}
}

If the interface is blank then it is a marker interface.
It can be used for applying restrict about the class, outside of the class. In keeping with the example below you can restrict a decorator to only be able to decorate Handlers of IProcessor.
A very valid reason is when applying a decorator:
Let's say the command parameter interface has a couple of properties:
public interface IProcessor
{
int Id { get; }
DateTime Date { get; }
}
We can define a decorator over all handlers of IProcessor commands that have the knowledge that all the command parameters have Id and Date:
public sealed class HandlerLogger<in T> where T : IProcessor
{
private readonly ILogger logger;
private readonly IHandlerLogger<T> decorated;
public HandlerLogger(
ILogger logger,
IHandlerLogger<T> decorated)
{
this.logger = logger;
this.decorated = decorated;
}
public void Handle(T command)
{
this.logger.Log(command.Id, command.Date, typeof(T).Name);
this.decorated.Handle(command);
}
}

There are different architectural patterns that can be used to pragmatically enforce types.
For example, if you were designing an API and you wanted to allow someone to extend it but you wanted to make sure that the class that was being created to extend your framework was a certain type and had a default parameterless constructor. Using generic typed interfaces is a common way to do this.
I have created a quick example adhoc to give a relatively simple overview of why a typed interface is useful in some models / architectural design.
public class UnitOfWorkManager<T>
{
private readonly IDataRepository _dataRepository;
private List<T> _unitOfWorkItems;
public UnitOfWorkManager(IDataRepository dataRepository)
{
_dataRepository = dataRepository;
}
public void AddUnitOfWork(IUnitOfWork<T> unitOfWork)
{
this._unitOfWorkItems.Add(unitOfWork);
}
public void Execute()
{
WorkerItem previous = null;
foreach (var item in _unitOfWorkItems)
{
var repoItem = _dataRepository.Get(item.Id);
var input = new WorkerItem(item.Id, repoItem.Name, previous);
previous = input;
}
}
}
public interface IUnitOfWork<T>
where T: WorkerItem, new()
{
string Id { get; }
void Execute(T input);
}
public class WorkerItem
{
public WorkerItem(string id, string name, WorkerItem previous)
{
this.Name = name;
this.Id = id;
this.Previous = previous;
}
public string Id { get; private set; }
public string Name { get; private set; }
public WorkerItem Previous { get; private set; }
}
Hope this helps.

Related

Dependency Injection outside of Controller

Good day. I have a problem of understanding the Dependency Injection.
So what exactly do I need is to have access from child objects to parent objects.
For example, I have my MainProgram object. This object creates another object, another object create 3-d objects and so on. Let's stop on child object #5
This child needs to have a reference to object #1.
I don't understand how to do this in a better way. But then I started to search and find something called Dependency Injection.
I really hope that this thing is the right answer for my issue (If not, please tell).
So here in my problem and example.
I'm trying to create a WEB API for one of my services. Using ASP .NET Core 6
First, I created a simple class that will be MainProgram, when Server will receive POST request with needed data, it will launch some working in multi-threading.
public class MainProgram
{
public int MaxThreads { get; set; }
public int OrderCounter { get; set; }
public AdjustableSemaphore Semaphore { get; set; }
public MainProgram(int maxThreads)
{
MaxThreads = maxThreads;
Semaphore = new AdjustableSemaphore(MaxThreads);
}
public async Task StartOperation(IApiOperation operation)
{
try
{
operation.Prepare();
operation.Start();
while (!operation.IsReady())
{
await Task.Delay(500);
}
operation.Finish();
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.Message);
Console.ResetColor();
}
}
public string OperationStatus(IApiOperation operation)
{
return operation.ShowDetails();
}
}
Then I added this class to Program.cs for Dependency.
builder.Services.AddSingleton(program => new MainProgram(1000));
I made a Constructor for my Controller as it was in the example I read and all worked great.
Controller create instance of MainProgram by its own.
[ApiController]
[Route("/")]
public class ApiController : ControllerBase
{
private MainProgram _mainProgram;
public ApiController(MainProgram mainProgram)
{
_mainProgram = mainProgram;
}
[HttpPost]
[Route("test")]
public string Get()
{
TestOperation to = new TestOperation(_mainProgram);
new Thread(() =>
{
var project = _mainProgram.StartOperation(to);
}).Start();
return $"Started task #{to.Id}";
}
}
The problems that I have are in this line
TestOperation to = new TestOperation(_mainProgram);
This TestOperation also has a Dependency from MainProgram. I understand that I can pass my private _mainProgram in it.
But let's pretend that TestOperation also has a child, and this child also has a child, and only the third one needs a link to MainProgram.
I thought that's where Dependency Injection helps.
Main Question is
How can I create objects that have a constructor with dependency for MainProgram,
If I cannot write new TestOperation(WITHOUT ATTRIBUTE)? It will be a syntax error.
I think you'd avoid the cycle of dependency;
If you couldn't avoid it ,you could try to inject the IServiceProvider into your services,and get the target service with provider.GetService() method,and you could try to create a Parameterservice or Static class to hold the parameter you need,
I tried as below :
Services:
interface IA {int methodA();}
interface IB { int methodB(); }
interface IC { int methodC(); }
interface IParameterService { }
public class ParameterService: IParameterService
{
public int APara;
public int BPara;
public ParameterService(int para)
{
APara = para+1;
}
}
public class A : IA
{
private readonly IServiceProvider _provider;
private readonly int Id;
public A(IServiceProvider provider)
{
_provider = provider;
Id = (provider.GetService(typeof(IParameterService)) as ParameterService).APara;
}
public int methodA()
{
return Id+1;
}
}
public class B : IB
{
private readonly IServiceProvider _provider;
public B(IServiceProvider provider)
{
_provider = provider;
}
public int methodB()
{
return (_provider.GetService(typeof(IA)) as A).methodA();
}
}
public class C : IC
{
private readonly IServiceProvider _provider;
public C(IServiceProvider provider)
{
_provider = provider;
}
public int methodC()
{
return (_provider.GetService(typeof(IB)) as B).methodB();
}
}
In startup:
services.AddTransient<IParameterService>(x => new ParameterService(1));
services.AddTransient<IA,A>();
services.AddTransient<IB,B>();
services.AddTransient<IC, C>();
in controller:
private readonly A _A;
private readonly C _C;
public SomeController(IServiceProvider provider)
{
_A = (A)provider.GetService(typeof(IA));
_C=(C)provider.GetService(typeof(IC));
}
Result:

Generic system for inferring the type of class required from given parameter type

I have a basic architecture for 'orders' in my game - each order has a basic data type and an 'order processor' which performs some action based on the given data. For example 'move to this point.'
I'd like to have a tidy system where I can simply pass in order data and the correct order processor will kick in, in such a way that I can easily add new OrderData/OrderProcessor classes without modifying other classes or messing around with enums or casting, so it seems like generics are the way to go.
This is the current code I have. I'm drawing a blank for how to draw a connection in the 'OrderService' class between the correct 'OrderProcessor' and 'IOrderData' pairs. See inside the OrderService<T> class for more information:
public interface IOrderData
{
}
// an order processor reads data from an IOrderData object until the data object says stop
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T m_currentData;
public virtual void Start(T data)
{
m_currentData = data;
}
}
////////////////////////
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
public override void Start(MoveOrderData data)
{
base.Start(data);
}
}
////////////////////////
public class OrderService<T> where T : IOrderData
{
private Dictionary<System.Type, OrderProcessor<T>> m_processors = new Dictionary<System.Type, OrderProcessor<T>>();
private OrderProcessor<T> m_currentProcessor;
public void GiveOrder(IOrderData data)
{
// this is the main problem: I'm not sure how to say "the given data is type 'MoveOrderData' so find out which
// OrderProcessor class handles those and pass it in". A simple switch statement and cast would suffice here
// but I'd like to automate the process
}
}
A possible solution here can be a making an OrderService class non-generic, because it can handle a different types of orders/order processors (according to comments). Then maintain a Dictionary<Type, Action<object>>, which wraps Action<object> to call Start method from OrderProcessor<T>.
I've extended the original code a little bit to show how it can work
public interface IOrderData
{
}
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class AttackOrderData : IOrderData
{
}
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T CurrentData { get; set; }
public virtual void Start(T data)
{
CurrentData = data;
}
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
}
public class AttackOrderProcessor : OrderProcessor<AttackOrderData>
{
}
public class OrderService
{
private readonly Dictionary<Type, Action<object>> m_processors = new Dictionary<Type, Action<object>>();
public OrderService()
{
AddProcessor(new MoveOrderProcessor());
AddProcessor(new AttackOrderProcessor());
}
private void AddProcessor<T>(OrderProcessor<T> processor) where T : IOrderData
{
var action = (Action<T>)processor.Start;
m_processors.Add(typeof(T), obj => action((T)obj));
}
public void GiveOrder(IOrderData data)
{
var action = m_processors[data.GetType()];
action?.Invoke(data);
}
}
It causes a downcasting obj => action((T)obj), but it shouldn't be a problem, since your data is constrained to IOrderData interface. Example of the usage
var service = new OrderService();
service.GiveOrder(new MoveOrderData());
service.GiveOrder(new AttackOrderData());

Appropriate design pattern for the payment modules c#

As i am learning through design pattern concept and also wanted to implement the payment modules in my project using the proper design pattern. So for that I have created some sample code.
Currently I have two concrete implementation for the payment PayPal and Credit Card. But the concrete implementation will be added further on the project.
Payment Service
public interface IPaymentService
{
void MakePayment<T>(T type) where T : class;
}
Credit Card and Pay Pal Service
public class CreditCardPayment : IPaymentService
{
public void MakePayment<T>(T type) where T : class
{
var creditCardModel = (CreditCardModel)(object)type;
//Implementation CreditCardPayment
}
}
class PayPalPayment : IPaymentService
{
public void MakePayment<T>(T type) where T : class
{
var payPalModel = (PayPalModel)(object)type;
//Further Implementation will goes here
}
}
Client Code Implementation
var obj = GetPaymentOption(payType);
obj.MakePayment<PayPalModel>(payPalModel);
Get Payment Option
private static IPaymentService GetPaymentOption(PaymentType paymentType)
{
IPaymentService paymentService = null;
switch (paymentType)
{
case PaymentType.PayPalPayment:
paymentService = new PayPalPayment();
break;
case PaymentType.CreditCardPayment:
paymentService = new CreditCardPayment();
break;
default:
break;
}
return paymentService;
}
I thought of implementing this modules using strategy design pattern, and I got deviated from Strategy and ended up doing this way.
Is this a proper way for creating the payment modules. Is there a more better approach of solving this scenario. Is this a design pattern?
Edited:
Client Code:
static void Main(string[] args)
{
PaymentStrategy paymentStrategy = null;
paymentStrategy = new PaymentStrategy(GetPaymentOption((PaymentType)1));
paymentStrategy.Pay<PayPalModel>(new PayPalModel() { UserName = "", Password = "" });
paymentStrategy = new PaymentStrategy(GetPaymentOption((PaymentType)2));
paymentStrategy.Pay<CreditCardModel>(
new CreditCardModel()
{
CardHolderName = "Aakash"
});
Console.ReadLine();
}
Strategy:
public class PaymentStrategy
{
private readonly IPaymentService paymentService;
public PaymentStrategy(IPaymentService paymentService)
{
this.paymentService = paymentService;
}
public void Pay<T>(T type) where T : class
{
paymentService.MakePayment(type);
}
}
Does this update inlines with the Strategy Pattern?
One major drawback of using an abstract factory for this is the fact that it contains a switch case statement. That inherently means if you want to add a payment service, you have to update the code in the factory class. This is a violation of the Open-Closed Principal which states that entities should be open for extension but closed for modification.
Note that using an Enum to switch between payment providers is also problematic for the same reason. This means that the list of services would have to change every time a payment service is added or removed. Even worse, a payment service can be removed from the strategy, but still be an Enum symbol for it even though it isn't valid.
On the other hand, using a strategy pattern doesn't require a switch case statement. As a result, there are no changes to existing classes when you add or remove a payment service. This, and the fact that the number of payment options will likely be capped at a small double-digit number makes the strategy pattern a better fit for this scenario.
Interfaces
// Empty interface just to ensure that we get a compile
// error if we pass a model that does not belong to our
// payment system.
public interface IPaymentModel { }
public interface IPaymentService
{
void MakePayment<T>(T model) where T : IPaymentModel;
bool AppliesTo(Type provider);
}
public interface IPaymentStrategy
{
void MakePayment<T>(T model) where T : IPaymentModel;
}
Models
public class CreditCardModel : IPaymentModel
{
public string CardHolderName { get; set; }
public string CardNumber { get; set; }
public int ExpirtationMonth { get; set; }
public int ExpirationYear { get; set; }
}
public class PayPalModel : IPaymentModel
{
public string UserName { get; set; }
public string Password { get; set; }
}
Payment Service Abstraction
Here is an abstract class that is used to hide the ugly details of casting to the concrete model type from the IPaymentService implementations.
public abstract class PaymentService<TModel> : IPaymentService
where TModel : IPaymentModel
{
public virtual bool AppliesTo(Type provider)
{
return typeof(TModel).Equals(provider);
}
public void MakePayment<T>(T model) where T : IPaymentModel
{
MakePayment((TModel)(object)model);
}
protected abstract void MakePayment(TModel model);
}
Payment Service Implementations
public class CreditCardPayment : PaymentService<CreditCardModel>
{
protected override void MakePayment(CreditCardModel model)
{
//Implementation CreditCardPayment
}
}
public class PayPalPayment : PaymentService<PayPalModel>
{
protected override void MakePayment(PayPalModel model)
{
//Implementation PayPalPayment
}
}
Payment Strategy
Here is the class that ties it all together. Its main purpose is to provide the selection functionality of the payment service based on the type of model passed. But unlike other examples here, it loosely couples the IPaymentService implementations so they are not directly referenced here. This means without changing the design, payment providers can be added or removed.
public class PaymentStrategy : IPaymentStrategy
{
private readonly IEnumerable<IPaymentService> paymentServices;
public PaymentStrategy(IEnumerable<IPaymentService> paymentServices)
{
this.paymentServices = paymentServices ?? throw new ArgumentNullException(nameof(paymentServices));
}
public void MakePayment<T>(T model) where T : IPaymentModel
{
GetPaymentService(model).MakePayment(model);
}
private IPaymentService GetPaymentService<T>(T model) where T : IPaymentModel
{
var result = paymentServices.FirstOrDefault(p => p.AppliesTo(model.GetType()));
if (result == null)
{
throw new InvalidOperationException(
$"Payment service for {model.GetType().ToString()} not registered.");
}
return result;
}
}
Usage
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var paymentStrategy = new PaymentStrategy(
new IPaymentService[]
{
new CreditCardPayment(), // <-- inject any dependencies here
new PayPalPayment() // <-- inject any dependencies here
});
// Then once it is injected, you simply do this...
var cc = new CreditCardModel() { CardHolderName = "Bob" /* Set other properties... */ };
paymentStrategy.MakePayment(cc);
// Or this...
var pp = new PayPalModel() { UserName = "Bob" /* Set other properties... */ };
paymentStrategy.MakePayment(pp);
Additional References:
Dependency Injection Unity - Conditional Resolving
Factory method with DI and IoC
This is one approach you could take. There's not a lot to go on from your source, and I'd really reconsider having MakePayment a void instead of something like an IPayResult.
public interface IPayModel { } // Worth investigating into common shared methods and properties for this
public interface IPaymentService
{
void MakePayment(IPayModel payModel);
}
public interface IPaymentService<T> : IPaymentService where T : IPayModel
{
void MakePayment(T payModel); // Void here? Is the status of the payment saved on the concrete pay model? Why not an IPayResult?
}
public class CreditCardModel : IPayModel
{
public string CardHolderName { get; set; }
}
public class PayPalModel : IPayModel
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class CreditCardPayment : IPaymentService<CreditCardModel>
{
public void MakePayment(CreditCardModel payModel)
{
//Implmentation CreditCardPayment
}
void IPaymentService.MakePayment(IPayModel payModel)
{
MakePayment(payModel as CreditCardModel);
}
}
public class PayPalPayment : IPaymentService<PayPalModel>
{
public void MakePayment(PayPalModel payModel)
{
//Implmentation PayPalPayment
}
void IPaymentService.MakePayment(IPayModel payModel)
{
MakePayment(payModel as PayPalModel);
}
}
public enum PaymentType
{
PayPalPayment = 1,
CreditCardPayment = 2
}
So following your implementation approach, it could look something like:
static class Program
{
static void Main(object[] args)
{
IPaymentService paymentStrategy = null;
paymentStrategy = GetPaymentOption((PaymentType)1);
paymentStrategy.MakePayment(new PayPalModel { UserName = "", Password = "" });
paymentStrategy = GetPaymentOption((PaymentType)2);
paymentStrategy.MakePayment(new CreditCardModel { CardHolderName = "Aakash" });
Console.ReadLine();
}
private static IPaymentService GetPaymentOption(PaymentType paymentType)
{
switch (paymentType)
{
case PaymentType.PayPalPayment:
return new PayPalPayment();
case PaymentType.CreditCardPayment:
return new CreditCardPayment();
default:
throw new NotSupportedException($"Payment Type '{paymentType.ToString()}' Not Supported");
}
}
}
I also think for a strategy/factory pattern approach, manually creating an IPayModel type doesn't make much sense. Therefore you could expand the IPaymentService as an IPayModel factory:
public interface IPaymentService
{
IPayModel CreatePayModel();
void MakePayment(IPayModel payModel);
}
public interface IPaymentService<T> : IPaymentService where T : IPayModel
{
new T CreatePayModel();
void MakePayment(T payModel);
}
public class CreditCardPayment : IPaymentService<CreditCardModel>
{
public CreditCardModel CreatePayModel()
{
return new CreditCardModel();
}
public void MakePayment(CreditCardModel payModel)
{
//Implmentation CreditCardPayment
}
IPayModel IPaymentService.CreatePayModel()
{
return CreatePayModel();
}
void IPaymentService.MakePayment(IPayModel payModel)
{
MakePayment(payModel as CreditCardModel);
}
}
Usage would then be:
IPaymentService paymentStrategy = null;
paymentStrategy = GetPaymentOption((PaymentType)1);
var payModel = (PayPalModel)paymentStrategy.CreatePayModel();
payModel.UserName = "";
payModel.Password = "";
paymentStrategy.MakePayment(payModel);
Your code is basically using the factory pattern. This is a good way to handle more than one method of payment
http://www.dotnettricks.com/learn/designpatterns/factory-method-design-pattern-dotnet

Inject a string property in a class using Ninject

One of my interfaces has a string property that will depend on where the interface is being used. I want to avoid hardcoding the property every time the object is created. I can set the property in constructor, but the object is injected using a factory.
The interface as follows:
public interface IObjectStore
{
string StorageTableName { get; set;}
void UpdateObjectStore(string key, string value);
string ReadObjectStore(string key);
}
Which is used in a service
public class CategoryService<T> : ICategoryService<T> where T : Company
{
private readonly IObjectStore objectStore;
public CategoryService(IObjectStore objStore)
{
this.objectStore = objStore;
objectStore.StorageTableName = "CategoryTable"; // I want to avoid this hard coding
}
...
}
The service is created using service factory (Ninject.Extensions.Factory)
public interface IServiceFactory
{
ICategoryService<T> CreateCategoryService<T>() where T : class;
}
Which is then injected using Ninject at the controller level. Here are my bindings
bool storeInNoSql = true;
kernel.Bind<IServiceFactory>().ToFactory().InSingletonScope();
kernel.Bind<ICategoryService<Article>>().To<CategoryService<Article>>();
kernel.Bind<IObjectStore>().ToMethod(ctx => storeInNoSql ? ctx.Kernel.Get<ObjectStore>() : null);
So the question is: how do i tell Ninject to set the property StorageTableName to "CategoryTable" everytime the object is injected into CategoryService and to "ArticleTable" everytime it is inserted into ArticleService?
I think this is what you are looking for.
It's just a very small sample project I just did, but this should solve your problem.
public class Ninject_34091099
{
public static void Run()
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IInterface<Generic1>>()
.To<Class<Generic1>>()
.WithConstructorArgument("name", "STRING ONE");
kernel.Bind<IInterface<Generic2>>()
.To<Class<Generic2>>()
.WithConstructorArgument("name", "The other string");
kernel.Bind<IServiceFactory>().ToFactory().InSingletonScope();
var factory = kernel.Get<IServiceFactory>();
var c1 = factory.CreateInterface<Generic1>();
var c2 = factory.CreateInterface<Generic2>();
Console.WriteLine(c1.Name);
Console.WriteLine(c2.Name);
}
Console.WriteLine("Done");
Console.ReadLine();
}
}
public interface IInterface<T> where T : class
{
string Name { get; set; }
}
public class Generic1
{
}
public class Generic2
{
}
public class Class<T> : IInterface<T> where T : class
{
public string Name { get; set; }
public Class(string name)
{
Name = name;
}
}
public interface IServiceFactory
{
IInterface<T> CreateInterface<T>() where T : class;
}
Sorry that the names mean nothing :D
Hope it helps

Pass any model with same base class

I have a email service which passes an email model through the constructor and that all using the same base class. For example one model could be for authentication, another model for password reset. My problem is how to allow the service to pass an anonymous model with the same base class.
sample code:
public class EmailService<T> : IEmailService
{
private readonly T _emailModel;
private readonly EmailType _emailType;
private readonly IEmailRepository _emailRepository;
private MailBuilder _mailBuilder;
private EmailTemplates _message;
public EmailService(T emailModel, EmailType emailType, IEmailRepository emailRepository)
{
_emailModel = emailModel;
_emailType = emailType;
_emailRepository = emailRepository;
getMessage();
constructEmail();
}
private void getMessage()
{
_message = _emailRepository.GetTemplateByUser((int)_emailType, _emailModel.UserTypeId);
}
private void constructEmail()
{
_mailBuilder = new MailBuilder(_message, _emailType, ObjectConverters.ConvertProperiesToDictionary(_emailModel));
}
public void Send()
{
EmailSettings emailSettings = SiteSettingsService.SiteConfiguration.EmailSettings;
MailSettings settings = new MailSettings
{
MailFrom = emailSettings.MailFrom,
MailSmtpHost = emailSettings.SmtpHost,
MailSmtpPort = emailSettings.SmtpPort,
EnableSsi = emailSettings.EnableSsi,
MailSmtpUsername = emailSettings.SmtpUsername,
MailSmtpPassword = emailSettings.SmtpPassword
};
new EmailSender(settings).SendEmail(_emailModel.EmailAddress, _message.Title, _mailBuilder.HtmlTemplate);
}
}
You could have the derived classes all implement a new IModel interface, which your EmailService class then accepts via ctor.
public class AuthenticationModel : BaseModel, IModel
{
public void PerformMainFunction()
{
// authenticate
}
}
public class PasswordResetModel : BaseModel, IModel
{
public void PerformMainFunction()
{
// reset password
}
}
public class BaseModel
{
public int UserTypeId { get; set; }
}
public interface IModel
{
void PerformMainFunction();
int UserTypeId { get; set; }
}
public class EmailService : IEmailService
{
private readonly IModel _emailModel;
...
public EmailService(IModel emailModel, EmailType emailType, IEmailRepository emailRepository)
{
_emailModel = emailModel;
...
You could use something like unity to inject the dependency or, for now, just do:
IModel model = new AuthenticationModel();
var eServ = new EmailService(model, ....
I thought of a better way. We always convert our object to a dictionary in the service. Maybe we convert it from the service calling the email service so we're always passing a dictionary instead of an interface, that way we don't need to know about the structure. The dictionary will always be a key value of string and string.

Categories

Resources