M. Rawan Ответов: 1

Как правильно использовать шаблон единицы работы


У меня есть класс 1 с какой-то простой работой, которая выглядит следующим образом :
public interface IClass1Repository {
        void insert(Class1 class1);
    }
    public class Class1
    {
        public object Id { get; set; }
        public string Name { get; set; }
    }
    public interface IClass1Service {
        void Insert(Class1 class1);
    }
    public class Class1Service : IClass1Service {
        public IClass1Repository _repo { get; set; }
        public Class1Service(IClass1Repository repo)
        {
            _repo = repo;
        }
        public void Insert(Class1 class1) {
            if (class1 == null) throw new Exception("class1 is null");
            if (string.IsNullOrWhiteSpace(class1.Name)) throw new Exception("class1 Name Cannot Be Null");
            _repo.insert(class1);
        }
    }


Что я уже пробовал:

позже в процессе разработки мне пришлось добавить второй класс ведьмы, у которого есть ссылка на class1, которая выглядит следующим образом :
public interface ISecondClassRepository
    {
        void insert(SecondClass secondClass);
    }
    public class SecondClass
    {
        public object Id { get; set; }
        public Class1 Class1 { get; set; }
        // Some Other Props

    }

    public class SecondClassService {
        ISecondClassRepository _repo;
        IClass1Service _class1Service;
        public SecondClassService(ISecondClassRepository repo,IClass1Service class1Service) {
            _repo = repo;
            _class1Service = class1Service;
        }

        public void Insert(SecondClass secondClass) {
            _class1Service.Insert(secondClass.Class1);
            _repo.insert(secondClass);
        }
        
    }

проблема с приведенным выше кодом заключается в том, куда поместить транзакцию?
если я пропущу class1Service.Insert вызовите и зависите от SecondClassRepository, чтобы сделать вставку, а затем как проверить логику и проверки для Class1.
Я чувствую, что что-то не так с моим подходом, но не могу понять, что именно.

PIEBALDconsult

Умеренно.

1 Ответов

Рейтинг:
7

johannesnestler

Я использую примерно одни и те же "вещи": (общий) репозиторий для каждого типа модели и общую UnitOfWork-реализацию. Я добавил еще один слой под названием "DataService", который имеет методы для комбинированного доступа к репозиторию (и другие вещи) в одном UnitOfWork.
Я не вижу для вас возможности сделать это в нынешней структуре. Так что, как всегда в программировании - просто добавьте еще один слой абстракции ;)


M. Rawan

Я вроде как застрял, как реализовать UOF без использования какого-либо фреймворка каждый пример, который я нашел в интернете, использует EF для обработки UOF и работы репозиториев, что делать, если в будущем я захочу использовать MongoDB (который не поддерживает транзакции по разным документам) или удаленный поставщик HTTP API?

johannesnestler

Hi again - As I said - just abstract it away - I use an abstract IUnitOfWork-Interface to implement my dataservices against (with Methods to Commit, Rollback, Save etc.), and have concrete Implementations for EF (SQLTransactions), even if you never change your provider this can be useful to keep the dependencies contained (think about updating to a new version). But if you ask me how likely it is that you really switch from one provider to another - VERY UNLIKELY - if it's not a toy-project…. (I'm an architect for large systems with ~30 years experience - i can't remember any customer who just switched the provider without re-implementing. So: don't abstract if you don't have to! Keep the YAGNI-principle high! - just my 2c... Kind regards Johannes

M. Rawan

вчера, когда я впервые прочитал ответ, я просто не понял его, теперь он кажется довольно очевидным, особенно после дальнейшего объяснения, большое спасибо.

johannesnestler

добро пожаловать - удачи вам в вашем проекте!