Принципы в C# - часть 6. Принцип инверсии зависимости.
Принцип инверсии зависимостей (сокращенно DIP) гласит:
Нужно полагаться на абстракции и их конкретную реализацию.
Преимущество инверсии зависимостей в том, что классам не нужно знать о конкретной реализации, а только о ее абстракции.
public class UserFileRepository
{
void SaveUser(User user);
}
public class UserService
{
public void CreateUser(User user)
{
UserFileRepository repository = new UserFileRepository();
repository.SaveUser(user);
}
}
Приведенный выше код совершенно хорош, но он не соблюдает принцип инверсии зависимостей. Класс User знает о конкретной реализации UserFileRepository
, что делает его слишком зависимым, если что-то нужно изменить в UserFileRepository
, то UserService
класс нужно будет изменить.
Мы можем решить эту проблему, изменив конкретную ссылку на файл interface
.
public interface IUserRepository
{
void SaveUser(User user);
}
public class UserFileRepository : IUserRepository
{
public void SaveUser(User user)
{
// Saves User to a file
}
}
public class UserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void CreateUser(User user)
{
_userRepository.SaveUser(user);
}
}
void Main()
{
IUserRepository repository = new UserFileRepository();
UserService userService = new UserService(repository);
User newUser = new User();
userService.CreateUser(newUser);
}
Теперь UserService
он зависит не от конкретной реализации, UserDBRepository
а от его контракта IUserRepository
.
Если приложению необходимо перейти от сохранения к файлу и сохранить его в базу данных, мы можем просто создать другую конкретную реализацию IUserRepository
и передать ее в качестве аргумента в UserService
.
public interface IUserRepository
{
void SaveUser(User user);
}
public class UserFileRepository : IUserRepository
{
public void SaveUser(User user)
{
// Saves User to a file
}
}
public class UserDBRepository : IUserRepository
{
public void SaveUser(User user)
{
// Saves User to a database
}
}
public class UserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void CreateUser(User user)
{
_userRepository.SaveUser(user);
}
}
void Main()
{
// Changed from File to DB repository
IUserRepository repository = new UserDBRepository();
UserService userService = new UserService(repository);
User newUser = new User();
userService.CreateUser(newUser);
}
В этом примере этот код можно изменить еще дальше, изменив, UserService
чтобы иметь свой интерфейс и реализовать его.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.