- Project Description
- Getting Started
- Usage
- Testing
- Development
- Technology Stack
- Code Examples
- Contributions
- License
- Contact Information
CampaignSort is a console-based application enabling users to sort and display selected marketing campaign data based on various attributes. This application can be used for quick campaign comparisons and to get insights into campaign performance metrics. The application is structured using the MVC (Model-View-Controller) architectural pattern. This ensures separation of concerns, where Models manage the application data, Views handle the user interface and presentation, and Controllers act as intermediaries, handling the communication between Models and Views. The goal of this project is to display my knowledge and use of TDD, OOP, SOLID, MVC, and clean code principles.
- .NET 6.0
- NUnit
- Clone the repository:
git clone https://github.com/jonahpena/CampaignSort.git
- Navigate to the project directory:
cd CampaignSort/CampaignSort/CampaignSort
- Build the project:
dotnet build
- Run the project:
dotnet run
Upon running the application, it will initially display a list of marketing campaigns. Input the number(s) of the campaigns you're interested in, separated by commas, or input 'all' to select all campaigns.
Following, it will present a list of attributes. You'll be asked to select an attribute to sort by, and then to choose additional attributes for display.
Once your selections have been made, the application will display your selected campaigns, sorted by the chosen attribute, and listing the attributes you selected.
This project uses NUnit for testing. To run the tests, navigate to the test project directory and use the following command:
dotnet test
The application follows the Model-View-Controller (MVC) pattern.
- Models: This directory contains classes that represent the data of the app. The main data class in our application is the
Campaign
class. - Views: This includes classes responsible for the user interface (console output in our case).
IUserInputInterface
and its implementations are part of this. - Controllers: These are classes that handle user input, manipulate the model, and cause the view to update.
CampaignSorter
can be seen as a part of this component.
These components work together to provide a well-structured and scalable architecture for the application.
To add a new attribute to the Campaign class, you need to:
- Add the new property to the Campaign class.
- Implement a new comparer in the
Controller/Comparers
directory, ensuring it complies with theICampaignComparer
interface. - Modify the
CampaignComparerFactory
to return your new comparer when necessary. - Update the Main function in
Program.cs
to include the new attribute in the attributes list.
Adding a new campaign is straightforward. Simply create a new instance of the Campaign class with the necessary attributes in the Main
method of the Program.cs
file.
- .NET 6.0: A free, cross-platform, open-source developer platform for building many different types of applications.
- C#: A modern, object-oriented programming language developed by Microsoft.
- MVC: An architectural design pattern that separates an application into three main logical components: the Model, the View, and the Controller. This pattern helps to achieve separation of concerns.
- NUnit: A unit-testing framework for all .Net languages.
- Usage of Interfaces (IUserInputInterface and ICampaignComparer): This allows us to define a contract for related classes and increases the flexibility of our application. It aligns with the Dependency Inversion Principle (D) of SOLID principles.
public interface ICampaignComparer
{
int Compare(Campaign x, Campaign y);
}
- Usage of Factory Pattern (CampaignComparerFactory): This creates and returns instances of classes that implement the ICampaignComparer interface. It allows our application to decide at runtime which class to use, promoting the Open/Closed Principle (O) of SOLID principles.
public class CampaignComparerFactory
{
public ICampaignComparer GetCampaignComparer(string attribute)
{
switch (attribute)
{
case "Name":
return new CampaignNameComparer();
case "StartDate":
return new CampaignStartDateComparer();
// Add other cases for each attribute as necessary
}
}
}
- Usage of Reflection: This is used in our application to dynamically read and display property values of the Campaign class. It enables our application to be flexible and adaptive to changes in the class structure.
foreach (var campaign in campaigns)
{
foreach (var attribute in attributeSelection)
{
PropertyInfo propertyInfo = typeof(Campaign).GetProperty(attribute);
Console.WriteLine($"{attribute}: {propertyInfo.GetValue(campaign)}");
}
Console.WriteLine("--------------------"); // Separator between campaigns
}
Contributions are what make the open-source community such an incredible place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (git checkout -b feature/AmazingFeature)
- Commit your Changes (git commit -m 'Add some AmazingFeature')
- Push to the Branch (git push origin feature/AmazingFeature)
- Open a Pull Request
Please make sure to update tests as appropriate. Also, ensure your code adheres to the existing coding standards within the project to make the integration process smoother.
Distributed under the MIT License. See LICENSE
for more information.
If you have any questions, concerns, or would like to collaborate on this project, please feel free to reach out:
- Email: jonahrpena@gmail.com
- LinkedIn: Jonah Pena