Injecting objects into each other - c#

The typical architecture I am using consists of Manager objects in the Business Layer. I am using DI/IOC within .NET Core/ .NET Standard. The managers are injected into the service layer and consequently the services are injected into our API controllers. So I am presently working in a Manager class. I now need a method that resides in another manager class.
Usually I return back through the service layer to the controller, then call the next service and then the manager through that.
I am wondering whether it is OK to just inject a Manager I require directly into the Manager I am working in. Therefore cutting out the trip back to the controller and then back up through the other service to the other manager. Basically I have 2 * Managers.
public class TypeCodeManager : ITypeCodeManager
{
public TypeCodeManager()
{
}
public async Task<int> GetTypeCodeAsync(string typeCode, string code)
}
public class UserManager : IUserManager
{
private readonly ITypeCodeManager _typeCodeManager;
public UserManager(ITypeCodeManager typeCodeManager)
{
_typeCodeManager = typeCodeManager
}
}
Is this generally a good idea?

I would say it's generally not a good idea to cross over into other domains through the "managers", assuming that your managers are what talks to the persistence layer. This will quickly lead to confusing dependency maps and code.
Your services are a much better layer to orchestrate the cross-domain concerns as they may describe cross domain workflows and depend on multiple managers.

Related

Calling Methods in Infrastructure Project from Application layer in Clean Architecture C#

I am pretty new to Clean Architecture in C#.
Based on the details my understanding was all the business logic must be in Application Layer and any infrastructure level things (DB Crud operations, Message handlings) must be in infrastructure layer.
So I have started the development, but found there is no dependency with infrastructure layer in application layer. Even why they are saying keep the business logic in application layer and infra operations in that layer.
Without that dependency how can I access the CRUD operations in infra layer.
Also there is dependency with Applicaiton layer in infrastructure layer which is I didnt understand.
Someone please help because I really got stuck with it. I have few methods in my application layer and I need to write the output into DB as well, which I dont know how to implement.
So simple it would be like this based on the description
Application Layer
IMessageBroker.cs
Public class IMessageBroker
{
Task<int> pushtoqueue(string queue, string message);
}
myservice.cs
public class myservice
{
public void MyMethod
{
//Here I need to call the pushtoqueue method which I dont know
}
}
Infrastructure Layer
MessageBroker.cs
public class messagebroker :Imessagebroker
{
public task<int> pushtoqueue(string queue, string message)
{
// here the queue pushing code comes
}
}
DependencyInjection.cs
services.Addscoped<IMessageBroker, MessageBroker>();
Please share your thoughts..
Environment
.NET 6
Azure Function Apps 4.0
The sample you linked to uses a concept called "inversion of control" (IoC). Adapted to your sample and defined in a (lengthy) sentence, this concept is about inverting the dependency from the Application layer to the Infrastructure layer so that the Application layer defines its requirements towards the Infrastructure layer (in form of interfaces) and can work with any Infrastructure layer that implements these interfaces.
If you look at the diagram in the overview section, there is an arrow from the Infrastructure layer to the Application layer. This expresses the dependency from the Infrastructure layer on the Application layer.
In your case, the components serve the following purpuse:
IMessageBroker: interface in Application layer that defindes the requirements that the Infrastructure layer has to fulfill.
MyService: service class that uses infrastructure components. An instance of type IMessageBroker should be injected into the class in order to access the message broker.
MessageBroker: concrete implementation of IMessageBroker.
The benefit of this approach is that you can easily replace infrastructure components without changing the application layer. While changing from one message broker to another might be comparatively seldom, being able to use mock objects when testing MyService is invaluable.
To answer the original question: how can you call the pushtoqueue method?
Just inject an instance of IMessageBroker into MyService and use it there:
public class MyService
{
private readonly IMessageBroker _msgBroker;
public MyService(IMessageBroker msgBroker)
{
_msgBroker = msgBroker;
}
public void MyMethod
{
//Here I need to call the pushtoqueue method which I dont know
_msgBroker.PushToQueue("queue", "message");
}
}
In your sample, you already add a registration of IMessageBroker to the IoC container, so the instance is injected when creating MyService.
As a side note: following naming conventions increases readability for fellow programmers. I've changed some of the names from the question. For an overview of the C# naming conventions see this link.

Providing access to different data stores with the Repository Pattern

I've been trying to learn how the service layer and repository pattern work. So far I've written a service layer and a simple repository pattern interface. However, I often see articles stating that the repository pattern allows for being able to swap in and out different data stores without the consuming code having to be changed.
In my case I want to be able to support reading and writing the application data to CSV and/or XML files. This is the part where I do not understand how to properly implement this with the repository pattern. Should I have a repository per data store?
ProductCsvRepository : IProductRepository
ProductXmlRepository : IProductRepository
However if I do this then the service layer would have to be aware of the underlying data store, which breaks the idea of being able to easily swap in and out different data stores.
Would I then have to have a service layer that looks like this?
private readonly IProductXmlRepository _productXmlRepository;
private readonly IProductCsvRepository _productCsvRepository;
public ProductService()
{
_productXmlRepository = new IProductXmlRepository();
_productCsvRepository = new IProductCsvRepository();
}
public ICollection<Product> GetAllXml()
{
return _productXmlRepository.GetAllCsv();
}
public ICollection<Product> GetAll()
{
return _productCsvRepository.GetAllXml();
}
This then raises two questions:
Surely this then breaks the idea of the consuming code needing to know what the data store is?
What about in the situations where the consuming code does need to know about the data store, such as for "File > Export As" type functionality? Should export functionality actually be a different service that utilises the appropriate CSV or XML service?
I think I am definetly not understanding how to correctly implement a repository patten and a service layer. How should I actually design repository patten and service layer?
Take a look at dependency injection and the plug-in pattern. They support injecting a concrete implementation of a repository. Your service layer then has only one reference to IProductRepository and a concrete repository gets injected. Something along the lines of this:
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
}
public class ConsumingClass {
{
private readonly IProductService _productService = new ProductService(new ProductXmlRepository());
// methods to use the the product service
}
But better would be to use a inversion of control container like NInject or SimpleInjector. Those frameworks can be used to link abstract classes (IProductRepository) to concrete classes (ProductXmlRepository or ProductXmlRepository) based on xml configurations.
Your application's solution should be structured following the Dependency Inversion Principle (http://deviq.com/dependency-inversion-principle/), so that there are at minimum three projects:
Core
Infrastructure
Your UI project
All (or nearly all) of your interfaces should be declared in Core (e.g. IProductRepository). Your interface implementations belong in Infrastructure, which references Core. Finally, your UI project should reference Core, but not necessarily Infrastructure (learn how to use types from a project without referencing it: http://blog.falafel.com/use-types-from-project-without-referencing/).
With this architecture in place, you can use dependency injection (http://deviq.com/dependency-injection/) to inject the desired implementation of a given type at runtime, which provides great flexibility and testability.
Setting up your solution with the proper dependencies between projects is critical to being successful with this approach, since a traditional UI -> Business Layer -> Data Layer setup will not allow you to invert dependencies. Once your solution is set up in this manner, you should follow the Explicit Dependencies Principle (http://deviq.com/explicit-dependencies-principle/) in all of your UI and service code.

Best pattern to be used for multiple payment gateways

Requirement:
I have requirement to integration with multiple payment gateways. However the client uses only one of the available, and that is configured using admin settings.
Current System:
I have written one library each per payment gateway. Which creates a maintenance nightmare and potential increase in projects as the gateway integration requests (sources) increase.
Question
Can someone suggest me a design pattern to use in this scenario, to may be create interfaces and common settings and implement the gateway as required which reduces duplicate code?
I would create a standard interface to deal with the common operations. Have a set of domain objects that are passed into those methods.
For example, to create a payment you might have a PaymentCardDetails model, an AddressModel etc. Your interface would have a method MakePayment or similar, e.g.:
public MakePaymentResponse MakePayment(PaymentCardDetails cardDetails, AddressModel address);
Then each of your payment gateways should implement this interface using their own implementation.
Then use IoC (Inversion of Control) / DI (Dependency Injection) to decide which interface to use at runtime based on a provided config value.
In the methods in your code that use the payment gateways you would pass in the interface using constructor injection, your DI framework would take care of picking the right implementation. e.g.
public class Payment {
private readonly IPaymentGateway _paymentGateway;
public Payment(IPaymentGateway paymentGateway) {
_paymentGateway = paymentGateway;
}
public MyMethod() {
//get your models prepared etc.
_paymentGateway.MakePayment(cardDetails, addressDetails);
}

What is the best design strategy for exposing multiple DataObjects/Methods within the .Net WCF service framework?

I'm relatively new the world of Microsoft WCF. I have a few questions regarding the best design pattern/method to use to implement one or more services that will address my needs.
I have an existing DataLayer which I would like to push into 1 or more WCF services. The backend database is ORACLE (and I have an entire data access layer which communicates with the correct version of ODAC).
When I look at my existing datalayer, I (more or less) have support for mulitple data objects (classes).
UserInfo
UserActivityHistoryAudit
Evaluations
EvaluationWorkFlowAndReview
EvaluationReports
I have several questions involving the best way to implement this in WCF.
Is it best to implement this as one service or several services (one which coincides with each data class/functionality)?
Ultimately, I would like to share the underlying Data Access layer which communicates with the ORACLE ODAC library. Is it best to embed this in a shared library, assembly?
If I go with multiple services, is it cleaner to hang them all off of the same endpoint?
What is the best strategy to use when designing this?
Thanks,
JohnB
the best way is to use one service that is WCF Data Service (OData)
here a sample you can download
http://code.msdn.microsoft.com/WCF-Data-Service-OData-ebb4214a
Often times, your business layer will also be implemented on the server. In such an event, you will simply wrap your business layer. If you do not have a business layer on the server side, model your service based on the same concept. You are exposing a set of functionality to target a specific consumer (or set of consumers). You will generally have one service to present to each consumer (or set of consumers). With that being said, you do not want one large monolithic service just to cover all of your potential needs. Break it down into logical areas.
Most of the time, wrapping a single data layer object is too small to wrap by itself. The exception is if you are simply servicing the data generically to everyone (very common with REST and ODATA services).
===========================
Model your services based off of consumption needs. One service per consumer set.
If you will be sharing your data layer across multiple business layers in different binaries, the data layer should exist in its own stand alone library and shared.
The endpoint layouts for your services are not generally important as long as you are consistent. At the end of the day, your consumers will simply copy/paste the endpoint that you provide.
Have you considered using Factory and Repository Pattern? Something like this.
`public interface IEmployee
{
// define your model here (properties, for example)
string FirstName {get; set;}
string LastName {get; set;}
}
public interface IEmployeeBizFactory
{
IEmployee CreateEmployee();
}
public class CustomEmployee : IEmployee
{
// Implementation here
}
public class CustomEmployeeBizFactory : IEmployeeBizFactory
{
public IEmployee CreateEmployee()
{
return new CustomEmployee();
}
}`
Consider Data Contracts for each of your data objects
Using Data Contracts

Repository / services pattern and data consistency

In a application that use Repositories and Services pattern, how to make sure Service layer is always called and not the Repositories directly ?
Example :
class OrderRepository
{
void CreateOrder(Order o)
...
}
class OrderService
{
void CreateOrder(Order o)
{
//make some business logic tests
...
//call repository
_orderRepository.CreateOrder(o);
}
}
I see two issues :
A programmer may call the repository directly because it doesn't know the existance of a service (sometimes its not as simple as in this example (1 service = 1 repository with same method names). some applications are not very well documented. or someone in hurry can forget to check if corresponding service exists (mistake)).
Totally different : long time ago someone created some views + controllers that use order repository directly. At that time there was no need to have some business logic check or additional operations, only order repository exists (because there it was not needed at all). If later, some additional operations when creating an order would be needed, a service will be created. the problem is that all controllers that make old repositories calls will need to be changed. Isn't repository principle/idea (and separating code in layers) supposed to make parts independent from each other ?
You can structure your solution so that all repositories and services are in their own respective projects, ex. Repositories and Services.
The only project that should reference Repositories would be Services. This way, other projects wouldn't have access to the repositories. Of course, nothing is to stop a developer from including the repositories project to the controllers project, but hopefully at this point they'll be asking themselves why it wasn't included in the first place.
Static analysis tools can help in this respect.
nDepend is a commercial tool that can be integrated into your build process and error on such a condition (any non service class calling a repository class directly).

Categories

Resources