IOC and interfaces

I have a project structure, for example:

CentralRepository.BL CentralRepository.BO CentralRepository.DataAccess CentralRepository.Tests CentralRepository.Webservices 

and there are so many dependencies between them. I want to use unity to reduce dependencies, so I'm going to create interfaces for my classes. My question is in which project the interfaces should be. My thoughts are that they should be in the BO layer. Can anyone give me some advice on this.

+6
source share
3 answers

At the combinatorial level, you have three options:

  • Defining Interfaces in a Separate Library
  • Defining interfaces with your customers
  • Define interfaces with your artists

However, the latter option is a really bad idea , because it tightly connects the interface with the developer (or vice versa). Since the whole point of introducing an interface is primarily to reduce communication , nothing is achieved thanks to this.

Defining an interface with a consumer is often enough, and personally I take only an additional step to define an interface in a separate library when disparate consumers play (this mainly happens if you send a public API).

+6
source

BOs are essentially your domain objects, or at least that's my guess. In general, if you are not using a template such as ActiveRecord, these are just state objects. The interface, on the other hand, defines behavior. Not a good concept, out of many “best practices,” to mix behavior and state. Now I’m most likely going a bit, but I think the background can help.

Now, to the question of where the interfaces should exist. There are several options.

  • Insert the interfaces into the library to which they belong.
  • Create a separate contract library

It’s easiest to stick to them in the same library, but then your layouts rely on the library as well as your tests. Not a huge deal, but it has a slight smell.

My usual method is to create such projects:

{company}. {program / project}. {worry (optional)}. {area}. {subarea (optional)}

The first two or three bits of the name are covered by the word "CentralRepository". In my case, it will be MyCompany.CentralRepository or MyCompany.MyProgram.CentralRepository, but the naming convention is not the main part of this post.

Parts of the "area" are the target of this post, and I usually use the following.

  • Setting up a library of domain objects (your BO): CentralRepository.Domain.Models
  • Domain Exception Library Configuration: CentralRepository.Domain.Exceptions
  • All / most other projects refer to the two above, as they represent the state in the application. Of course, all business libraries use these objects. The sustainability library may have a different model, and I may have a presentation model in the experience library (s).
  • Set up the main library as follows: CentralRepository.Core (can have subareas?). this is where the business logic lies (the actual application, because persistence and changes in experience should not affect the core functions).
  • Set up a test library for the kernel: CentralRepository.Core.Test.Unit.VS (I have Unit.VS to show this unit tests, not integration tests with the unit test library, and I use VS to indicate MSTest - others will have different names).
  • Create tests, and then customize business functionality. Configure the interfaces as needed. Example
  • Data from DAL is needed, therefore, for the data used for Core tests, the interface and layout are configured. The name here will be something like CentralRepository.Persist.Contracts (a subarea can also be used if there are several types of persistence).

The main concept here is “Core as Application”, not the n-level (they are compatible, but thinking only about business logic, as a paradigm, allows you to freely combine with perseverance and experience).

Now back to your question. The way to configure the interfaces is based on the location of the "conjugate" classes. So I will probably have:

CentralRepository.Core.Contracts CentralRepository.Experience.Service.Contracts CentralRepository.Persist.Service.Contracts CentralRepository.Persist.Data.Contracts

I am still working with this, but the basic concept is my IoC, and testing should be considered, and I should be able to isolate testing, which is better achieved if I can isolate contracts (interfaces). Logical separation is fine (one library), but as a rule, I do not head this way because there are at least a couple of green developers who find it difficult to see logical separation without physical separation. Your mileage may vary .: -0

Hope this mess helps in some way.

+1
source

I would suggest storing interfaces wherever their executors are in most cases, if you are talking about assemblies.

Personally, when I use a multi-level approach, I try to give each layer its own assembly and give a link to the layer below it. In each layer, most public things are interfaces. So, at the data access level, I could have ICustomerDao and IOrderDao as open interfaces. I will also have public Dao factories in the DAO assembly. Then I will have specific implementations marked as internal - CustomerDaoMySqlImpl or CustomerDaoXmlImpl that implement the open interface. The public factory then provides implementations to users (i.e. the domain layer) without users knowing exactly which implementation they are receiving - they provide information for the factory, and the factory turns around and passes them the ICustomerDao that they use.

The reason I mention all of this is to lay the foundation for understanding which interfaces really should be - the contracts between the servicer and the client API. Thus, in terms of dependency, you want to define the contract, in general, where the service provider is located. If you define it elsewhere, you can potentially not manage your dependencies with interfaces, and instead just introduce an intangible layer of indirection.

One way or another, I would say that your interfaces as they are are a contract with your customers regarding what you intend to provide, while maintaining personal information about how you intend to provide it. This is probably a good heuristic that will make it more intuitive where to put the interfaces.

-1
source

Source: https://habr.com/ru/post/899144/


All Articles