Как избежать дублирования кода в проекте c #

#c# #design-patterns #refactoring

#c# #шаблоны проектирования #рефакторинг

Вопрос:

У меня ситуация, когда я использую пользовательский плагин specflow. Используя пользовательский плагин specflow, у меня есть два разных проекта, скажем, Project_A и Project_B. Оба проекта имеют свой собственный репозиторий.

Project_A имеет класс ниже (пожалуйста, найдите фрагмент кода) :

 public class CustomTestGeneratorProvider : IUnitTestGeneratorProvider
{
    public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
    {
        _unitTestGeneratorProvider = new 
        NUnit3TestGeneratorProvider(codeDomHelper);
        CodeDomHelper = codeDomHelper;
    }

    public UnitTestGeneratorTraits GetTraits()
    {
        return _unitTestGeneratorProvider.GetTraits();
    }

    public void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
        string featureDescription)
    {
        _unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
        generationContext.Namespace.Imports.Add(new CodeNamespaceImport("Com.MyOrg.Custom.Core.Feature"));
        generationContext.TestClass.BaseTypes.Add("MyOrgTest");
     }

    public void SetTestClassCategories(TestClassGenerationContext generationContext,
        IEnumerable<string> featureCategories)
    {
        _unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
    }
  

Project_B имеет класс ниже (пожалуйста, найдите фрагмент кода) :

 public class CustomTestGeneratorProvider : IUnitTestGeneratorProvider
{
    public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
    {
        _unitTestGeneratorProvider = new 
        NUnit3TestGeneratorProvider(codeDomHelper);
        CodeDomHelper = codeDomHelper;
    }

    public UnitTestGeneratorTraits GetTraits()
    {
        return _unitTestGeneratorProvider.GetTraits();
    }

    public void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
        string featureDescription)
    {
        _unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
    }

    public void SetTestClassCategories(TestClassGenerationContext generationContext,
        IEnumerable<string> featureCategories)
    {
        _unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
    }
  

Если вы посмотрите на метод SetTestClass в классе, он имеет другую реализацию логики. Это единственный метод, который становится для меня поддержкой. Обратите внимание, что оба проекта выполняют одно и то же, но пользователь для них разный. Во время выпуска, если я что-то изменю в Project_A, я должен позаботиться или подумать и о Project_B.

Я хотел бы свести к минимуму это обслуживание. Что я должен сделать, чтобы сократить обслуживание?. Как избежать дублирования кода? в таком сценарии.

Комментарии:

1. создание некоторых интерфейсных / базовых классов и ссылок на версии в обоих проектах?

Ответ №1:

Возьмите все общие части классов и создайте из них абстрактный базовый класс. Оставьте SetTestClass метод abstract .
Поместите этот класс в отдельную dll:

 public abstract class TestGeneratorProvider : IUnitTestGeneratorProvider
{
    public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
    {
        _unitTestGeneratorProvider = new 
        NUnit3TestGeneratorProvider(codeDomHelper);
        CodeDomHelper = codeDomHelper;
    }

    public UnitTestGeneratorTraits GetTraits()
    {
        return _unitTestGeneratorProvider.GetTraits();
    }

    public abstract void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
        string featureDescription)

    public void SetTestClassCategories(TestClassGenerationContext generationContext,
        IEnumerable<string> featureCategories)
    {
        _unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
    }
}
  

В проекте A добавьте ссылку на эту dll, унаследуйте этот класс и предоставьте соответствующую SetTestClass реализацию:

 public class CustomTestGeneratorProvider : TestGeneratorProvider
{
    public override void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
    string featureDescription)
    {
        _unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
        generationContext.Namespace.Imports.Add(new CodeNamespaceImport("Com.MyOrg.Custom.Core.Feature"));
        generationContext.TestClass.BaseTypes.Add("MyOrgTest");
     }
}
  

И сделайте то же самое в проекте B:

 public class CustomTestGeneratorProvider : TestGeneratorProvider
{
    public override void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
    string featureDescription)
    {
        _unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
    }
}
  

Ответ №2:

Создайте отдельный проект с этим классом и «базовой реализацией» для методов. Если вам нужно внести изменения исключительно в один, используйте переопределение, чтобы переопределить метод.

Ссылка: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/override