I am working in a content management system that uses C# and allows for adding separate code in a central class. One issue that has come up is we would like to have a separate code base for QA and the rest of the site, currently we use the folder structure to switch the call from one class to the other
if (AssetPath == "Websites QA")
{
InputHelperQA.Navigation();//Calling Navigation Section From Helper Class
}
else
{
InputHelper.Navigation();
}
But i feel it is a very tedious way of doing this task. Is there a better way of accomplishing this?, obviously just appending InputHelper + "QA" does not work but some thing along those lines where we only have to call the method once instead of having to wrap an if else around the call.
You really shouldn't have separate code for different environments, besides being branches representing your environments.
You really should store your configuration in a config file or database.
You could do worse than:
1) Have an interface (which you may already have, truth be told)
public interface IInputHelper
{
void Navigation();
}
2) Derive your two instances as you already have:
public class InputHelper : IInputHelper { }
public class InputHelperQA : IInputHelper { }
3) Create some kind of a dispatch manager:
public sealed class InputDispatch
{
private Dictionary<string, IInputHelper> dispatch_ = new Dictionary<string, IInputHelper>(StringComparer.OrdinalIgnoreCase);
public InputDispatch()
{
dispatch_["Websites QA"] = new InputDispatchQA();
dispatch_["Default"] = new InputDispatch();
}
public void Dispatch(string type)
{
Debug.Assert(dispatch_.ContainsKey(type));
dispatch_[type].Navigation();
}
}
I would use Dependency Injection. StructureMap (as just one example) will let you specify which concrete type to provide for an interface via a config file.
http://docs.structuremap.net/XmlConfiguration.htm
Related
For my project purpose I need to send metrics to AWS.
I have main class called SendingMetrics.
private CPUMetric _cpuMetric;
private RAMMetric _ramMetric;
private HDDMetric _hddMetric;
private CloudWatchClient _cloudWatchClient(); //AWS Client which contains method Send() that sends metrics to AWS
public SendingMetrics()
{
_cpuMetric = new CPUMetric();
_ramMetric = new RAMMetric();
_hddMetric = new HDDMetric();
_cloudwatchClient = new CloudwatchClient();
InitializeTimer();
}
private void InitializeTimer()
{
//here I initialize Timer object which will call method SendMetrics() each 60 seconds.
}
private void SendMetrics()
{
SendCPUMetric();
SendRAMMetric();
SendHDDMetric();
}
private void SendCPUMetric()
{
_cloudwatchClient.Send("CPU_Metric", _cpuMetric.GetValue());
}
private void SendRAMMetric()
{
_cloudwatchClient.Send("RAM_Metric", _ramMetric.GetValue());
}
private void SendHDDMetric()
{
_cloudwatchClient.Send("HDD_Metric", _hddMetric.GetValue());
}
Also I have CPUMetric, RAMMetric and HDDMetric classes that looks pretty much similar so I will just show code of one class.
internal sealed class CPUMetric
{
private int _cpuThreshold;
public CPUMetric()
{
_cpuThreshold = 95;
}
public int GetValue()
{
var currentCpuLoad = ... //logic for getting machine CPU load
if(currentCpuLoad > _cpuThreshold)
{
return 1;
}
else
{
return 0;
}
}
}
So the problem I have is that clean coding is not satisfied in my example. I have 3 metrics to send and if I need to introduce new metric I will need to create new class, initialize it in SendingMetrics class and modify that class and that is not what I want. I want to satisfy Open Closed principle, so it is open for extensions but closed for modifications.
What is the right way to do it? I would move those send methods (SendCPUMetric, SendRAMMetric, SendHDDMetric) to corresponding classes (SendCPUMetric method to CPUMetric class, SendRAMMEtric to RAMMetric, etc) but how to modfy SendingMetrics class so it is closed for modifications and if I need to add new metric to not change that class.
In object oriented languages like C# the Open Closed Principle (OCP) is usually achieved by using the concept of polymorphism. That is that objects of the same kind react different to one and the same message. Looking at your class "SendingMetrics" it's obvious that the class works with different types of "Metrics". The good thing is that your class "SendingMetrics" talks to a all types of metrics in the same way by sending the message "getData". Hence you can introduce a new abstraction by creating an Interface "IMetric" that is implemented by the concrete types of metrics. That way you decouple your "SendingMetrics" class from the concrete metric types wich means the class does not know about the specific metric types. It only knows IMetric and treats them all in the same way wich makes it possible to add any new collaborator (type of metric) that implements the IMetric interface (open for extension) without the need to change the "SendingMetrics" class (closed for modification). This also requires that the objects of the different types of metrics are not created within the "SendingMetrics" class but e.g. by a factory or outside of the class and being injected as IMetrics.
In addition to using inheritance to enable polymorphism and achiving OCP by introducing the interface IMetric you can also use inheritance to remove redundancy. Which means you can introduce an abstract base class for all metric types that implements common behaviour that is used by all types of metrics.
Your design is almost correct. You got 3 data retriever and 1 data sender. So it's easy to add more metric (more retriever) (open for extensions) without affecting current metrics (closed for modifications), you just need a bit more refactor to reduce duplicated code.
Instead of have 3 metrics classes look very similar. Only below line is different
var currentCpuLoad = ... //logic for getting machine CPU load
You can create a generic metric like this
internal interface IGetMetric
{
int GetData();
}
internal sealed class Metric
{
private int _threshold;
private IGetMetric _getDataService;
public Metric(IGetMetric getDataService)
{
_cpuThreshold = 95;
_getDataService = getDataService;
}
public int GetValue()
{
var currentCpuLoad = _getDataService.GetData();
if(currentCpuLoad > _cpuThreshold)
{
return 1;
}
else
{
return 0;
}
}
}
Then just create 3 GetMetric classes to implement that interface. This is just 1 way to reduce the code duplication. You can also use inheritance (but I don't like inheritance). Or you can use a Func param.
UPDATED: added class to get CPU metric
internal class CPUMetricService : IGetMetric
{
public int GetData() { return ....; }
}
internal class RAMMetricService : IGetMetric
{
public int GetData() { return ....; }
}
public class AllMetrics
{
private List<Metric> _metrics = new List<Metric>()
{
new Metric(new CPUMetricService());
new Metric(new RAMMetricService());
}
public void SendMetrics()
{
_metrics.ForEach(m => ....);
}
}
I just started testing Marten (2.9), and so far I am loving it. However, I am not sure I am following the DocumentStore.For method. For example, in my "dbhandler" for Marten, I can write:
public MartenDbHandler()
{
store = DocumentStore.For(_ =>
{
_.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
_.Connection("host=localhost;database=marten;password=root;username=postgres");
_.Schema.For<Customer>().Index(x => x.PopulationRegistryNumber);
});
}
but naturally, I do not want to have all that schema code when I initialize the database and supply the connection string.
So I thought, maybe I can pass on the store variable, and do the same, but then the For thing doesn't exist:
... and I haven't really found a way to set the Schema in any other way.
What I really want to do is to have an Interface, that is dynamically loaded and executed (via Reflection) when I start my application, that handles those things, like an IMartenMetaData that looks something like:
public interface IMartenMetaData
{
SetMetaData(DocumentStore store);
}
and then implement the schema things in that/those classes, but that doesn't work because I can't use the DocumentStore to set the meta.
Keep it simple. The document store is supposed to have a single instance in your app and you define the schema properties during construction. No need to abstract the store.
One way is you can create your own implementation of DocumentStore. You can refer to the test document store classes in the source code.
Update:
You can find the sample here https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/TestingDocumentStore.cs
I managed to do a much nice approach to keep it more dynamic and not all in the construction of DocumentStore.
Please see code below. The idea is straightforward:
Create the StoreOptions separately
Before creation of the DocumentStore, run method that via Reflection finds all classes of a certain Type that will add table meta data
Create the DocumentStore
public MartenDbHandler()
{
StoreOptions so = new StoreOptions();
so.Connection("host=localhost;database=marten;password=root;username=postgres");
so.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
SetTableMeta(so);
store = new DocumentStore(so);
}
private void SetTableMeta(StoreOptions storeOptions)
{
// We get the current assembly through the current class
var currentAssembly = Assembly.GetExecutingAssembly();
// we filter the defined classes according to the interfaces they implement
var stuff = currentAssembly.DefinedTypes.Where(type => type.IsSubclassOf(typeof(MartenTableMetaDataBase))).ToList();
foreach (Type type in stuff)
{
IMartenTableMetaData temp = (IMartenTableMetaData)Activator.CreateInstance(type);
temp.SetTableMetaData(storeOptions);
}
OnLogEvent?.Invoke(this, $"{stuff.Count} table meta data initialized");
}
The IMartenTableMetaData is a base class for the IMartenTableMetaData interface. In the example below, the base class isn't used, but I normally find it good to have a base class (I use a similar approach to another ORM, where I actually use the base class). But, the base class can of course be removed if you have no use for it.
internal abstract class MartenTableMetaDataBase : IMartenTableMetaData
{
public void SetTableMetaData(StoreOptions storeOptions)
{
SetSpecificTableMetaData(storeOptions);
}
protected abstract void SetSpecificTableMetaData(StoreOptions storeOptions);
}
and the interface:
public interface IMartenTableMetaData
{
void SetTableMetaData(StoreOptions storeOptions);
}
So, I can now create a class for each Type I want to add meta data too, like this:
internal class MartenTableMetaDataCustomer : MartenTableMetaDataBase
{
protected override void SetSpecificTableMetaData(StoreOptions storeOptions)
{
storeOptions.Schema.For<Customer>().Index(x => x.Muni);
}
}
or
internal class MartenTableMetaDataDriver : MartenTableMetaDataBase
{
protected override void SetSpecificTableMetaData(StoreOptions storeOptions)
{
storeOptions.Schema.For<Driver>().Index(x => x.Username);
}
}
etc.
This will keep the Marten DB handler clean and meta data separated into specific classes for readability, clarity and all that stuff =)
I'm trying to create a mechanism that will allow the application to decide (in runtime) whether to execute some functionality.
"Some Functionality" can be anything, it can be c# code which is contained in several classes in several dlls, it can be UI, it can be database query execution, etc.
Most importantly, it should fit in the current existing infrastructure I have, which I cannot re-design and build from scratch.
The more I think of it, it seems like the only solution I can use would be to hold some table which will be the "functionality repository" and it will tell (by unique key) if a functionality is on / off.
Then in code, I will have to place in each spot which handles such functionality an if else statement.
E.g.
If(functionalityEnabled)?
DoFunctionality()
Else
DoTheUsusal()
Is there a better way or a better design to implement it? I would like to keep the solution as simple as possible, but on the other hand, this solution is really ugly and will eventually make my code looks like spaghetti code.
Your thoughts will be appreciated,
I'm using c# with sql server, web api for web services.
Edit:
I want to say that I appreciate the time and effort of everyone answering my question, there were some really interesting ideas that you brought up.
I eventually marked #dasblinkenlight answer since it suited by need the best, though other answers here are really good and may be useful to others.
Thank you.
If you have two classes that implement the same interface, your application can call the functionality (methods, properties) of the class without knowing exactly if it is calling the basic functionality or the alternative functionality:
IFunctionalityX {
DoIt();
}
class BasicFunctionalityX: IFunctionalityX {
public DoIt() {
// Default behaviour goes here
}
}
class PluginFunctionalityX: IFunctionalityX {
public DoIt() {
// Alternative functionality.
}
}
If PluginFunctionalityX shares parts of its implementation with BasicFunctionalityX, you may inherit it from the other, but whether you do or not doesn't really matter. As long as you use the interface, that is what counts, and you can use this method regardless of whether the classes are related or not.
In the initialization of your program, you can make the decision once and create an instance of the right class. You may store this class in some container that holds all your functionalities. FunctionalityX is a property of interface IFunctionalityX, and you can make other interfaces (and properties) for other functionalities.
if (functionalityXEnabled) {
FunctionalityContainer.FunctionalityX = new PluginFunctionality();
} else {
FunctionalityContainer.FunctionalityX = new BasicFunctionality();
}
Then, in the rest of your application, you can call your functionality through:
FunctionalityContainer.FunctionalityX.DoIt();
Instead of implementing this from scratch you may use a dependancy injection library, like Unity. This also allows you to more easily get an instance of the right functionality at the time you need it without having to create them all at the start of your program, and without writing elaborate constructor code for all fucntionalities.
You want to dispatch your code differently at runtime dependent on a configuration setting. Conditionals and polymorphism are two ways of doing so.
Conditionals
At runtime, check for values using if, switch or other lookup methods. You're already doing these.
if (configFile.cloudAccount == null) {
saveFileToDisk();
} else saveFileToCloud();
Advantages
They're conditionals, you really can't avoid having to do one at some point in any nontrivial development project
Disadvantages
Doing them at every point in your application would be painful, though. So they're best combined with other strategies to minimise their use
Polymorphism
When loading your application, read through the configuration file and construct your application's components accordingly:
interface IFileSaver { /* Used to save files in your application */ }
class DiskSaver : IFileSaver { /* The default file saving class */ }
class CloudSaver : IFileSaver { /* If they've configured a cloud account */ }
// EXAMPLE USE
int Main (...) {
// Setup your application, load a config file.
// You'll need to check the config with a conditional
// here (uh oh) but other components of your application
// will just use the IFileSaver interface
if (configFile.cloudAccount != null) {
YourApplication.FileSaver = new CloudSaver(configFile.cloudAccount);
} else {
YourApplication.FileSaver = new DiskSaver();
}
}
// Somewhere else in your application
void SaveCurrentDocument() {
// No if's needed, it was front loaded when initialising
// the application
YourApplication.FileSaver.Save();
}
Advantages
Fits in nicely with object-oriented design
All your configuration checks are front loaded. After loading in the correct classes the rest of your program will use them, oblivious to their actual implementation. Because of that, you don't need to do if checks throughout your code.
Compiler will be able to statically check type errors in your approach
Disadvantages
Only as flexible as your class's interface. Maybe you want some extra steps and checks to occur with a CloudSaver, they'd better fit into the pre-existing interface; otherwise, they won't happen.
Long story short - conditionals let you explicitly perform the checks whenever they're needed so, in principle, you get a lot of procedural flexibility. For example, maybe the SaveAs routine needs to save files slightly differently than the Save routine. However, as you've identified, this leads to long repetitive code. In those cases, structuring your code to use polymorphism might help out.
Either way, you will almost certainly need to have some amount of conditional checks wherever there is flexibility in your application.
Note: There are many other ways of achieving runtime config checks, I'm just pointing out the most common (and usually straightforward)
A once-popular quip among OO programmers has been that every conditional in the code indicate a missed opportunity to subclass. Although this rule is far from being universal, and it falls short when it comes to composition, there is a grain of truth to it, especially when you see the same condition popping up in multiple ifs across different methods of the same class.
A common way of dealing with ifs like that is using some combination of inheritance and composition, and moving the decision to a single place where your object is being created.
The inheritance way looks like this:
interface Doer {
void doSomething();
}
class BasicDoer implements Doer {
public void doSomething() {
...
}
}
class EnhancedDoer extends BasicDoer {
public void doSomething() {
base.doSomething();
...
}
}
// At construction time:
Doer doer;
if (someCondition)
doer = new BasicDoer();
else
doer = new EnhancedDoer();
The composition way looks like this:
interface Doer {
void doSomething();
}
// Create several implementations of Activity, then...
// At construction time:
List<Doer> doers = new ArrayList<>();
if (someCondition1)
doers.add(new SomeKindOfDoer());
if (someCondition2)
doers.add(new AnotherKindOfDoer());
if (someCondition3)
doers.add(new YetAnotherKindOfDoer());
Now instead of an if you do this:
for (Doer d : doers) {
d.doSomething();
}
If it's just a single condition then you have no choice but to use if else and is perfect for single conditions.
If you have more then 1 condition, you may think of using Switch statement.
As far as you are worried about your code going to look complicated with if else statement, put your code within functions,
if(condition)
{
DoThis();
}
else
{
DoSomethingElse();
}
Maybe something similar to strategy design pattern (incapsulation of behaviour) will make it more managable if functionality doesn't require lots of interaction with object data (though interaction is possible). Pros: readable extendable code, cons: lots of code.
namespace SomethingLikeStrategy
{
public interface Behaviour {
void doThis();
void changeM(ref int m);
void doThat();
}
public class BehaviourOriginal : Behaviour {
public void doThis() {
Console.WriteLine("foo");
}
public void changeM(ref int m) {
m = 20;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class BehaviourSpecial : Behaviour {
public void doThis() {
Console.WriteLine("bar");
}
public void changeM(ref int m) {
m = 10;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class MyClass {
Behaviour mBehaviour;
int mM = 0;
public MyClass() {
mBehaviour = new BehaviourOriginal();
}
public void setSpecialBehaviour(bool special) {
if (special) {
mBehaviour = new BehaviourSpecial();
} else {
mBehaviour = new BehaviourOriginal();
}
}
public void doThis() {
mBehaviour.doThis();
}
public void doThat() {
mBehaviour.doThat();
}
public void changeM() {
mBehaviour.changeM(ref mM);
}
public void printM() {
Console.WriteLine(mM);
}
}
class Program
{
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.doThis();
myClass.setSpecialBehaviour(true);
myClass.doThis();
myClass.setSpecialBehaviour(false);
myClass.printM();
myClass.changeM();
myClass.printM();
myClass.setSpecialBehaviour(true);
myClass.changeM();
myClass.printM();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
I'm trying to write code as better I can, for that reason looking at some code I wrote in past I've seen that I access to .config appsetting with something as
Public void Do()
{
Var x = ConfigurationManager.AppSettings.Get("foo");
doSomethingElse(x);
}
Writing test on this method I asked myself wasn't it better to have an interface with properties that exposes all the .config AppSettings values ? This would allow me to replace via IoC the real implementation.
on the other side I ask is it correct to wrap all those values in a class/interface?what if I've different assemblies that compose an application and I need to access to that object? Supposed that it will be in a shared project does it make sense to have a value as
Int ModelAvalue {get{};}
Defined in that class that would never be used in ModelB?
Configuration is a dependency. I think your idea about creating an interface that returns the most appropriate type helps both with testing and makes your code easier to understand. It also gives you the flexibility to change where your configuration is stored in the future.
To answer your other question, it would be better to have interfaces smaller and more specific, as per the interface segregation principle. You could have different interfaces in which each interface is a group of closely related settings. For example, you would not have an interface that has your database connection string and your log file path.
public interface IDatabaseConfiguration
{
string ConnectionString { get; }
}
public interface IBlogConfiguration
{
int NumberOfPostsPerPage { get; }
}
public class AppConfiguration : IDatabaseConfiguration, IBlogConfiguration
{
public string ConnectionString
{
get { return ConfigurationManager.ConnectionStrings["MyDb"].ConnectionString; }
}
public int NumberOfPostsPerPage
{
get { return int.Parse(ConfigurationManager.AppSettings["PostsPerPage"]); }
}
}
In the future, if you decide that NumberOfPostsPerPage should be stored elsewhere, you can create a different concrete implementation of IBlogConfiguration
All of our reports are created from object graphs that are translated from our domain objects. To enable this, we have a Translator class for each report, and have been using Dependency Injection for passing in dependencies.
This worked great, and would yield nice classes structured like this:
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc)
{
_empSvc = empSvc;
_paySvc = paySvc;
}
public Check CreateCheck()
{
//do the translation...
}
}
However, in some cases the mapping has many different grouping options. As a result, the c-tor would turn into a mix of class dependencies and parameters.
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc
, bool doTranslateStubData
, bool doAttachLogo)
{
_empSvc = empSvc;
_paySvc = paySvc;
_doTranslateStubData = doTranslateStubData;
_doAttachLogo = doAttachLogo;
}
public Check CreateCheck()
{
//do the translation...
}
}
Now, we can still test it, but it no longer really works with an IoC container, at least in a clean fashion. Plus, we can no longer call the CreateCheck twice if the settings are different for each check.
While I recognize it's a problem, I don't necessarily see the right solution. It seems kind of strange to create a Factory for each class ... or is this the best way?
Shot in the dark here, but could you move those parameters to the method instead?
In other words:
public Check CreateCheck(bool doTranslateStubData, bool doAttachLogo)
{
//do the translation...
}
Do those parameters have to be passed in via the constructor?
(Note - if your response to this is "there are too many methods for that to be practical", then part of the problem may be that the abstraction is too coarse).
Another option (it's really hard to say without understanding the domain model and injection patterns) would be to introduce a parameter object that is itself managed by the injector:
public interface ICheckConfiguration
{
bool AttachLogo { get; }
bool TranslateStubData { get; }
}
Then inject this with the constructor:
public CheckTranslator (IEmployeeService empSvc, IPaycheckService paySvc,
ICheckConfiguration config)
{
// etc.
}
This should be enough. You can then create a concrete CheckConfiguration class that takes those two bool properties in its constructor, and configure your container to create different instances of the parameter object (interface) based on a higher-level DI parameter.
The last thing I think I should mention is that just because you're using DI doesn't mean that everything has to be managed by the container. It's not such a bad thing to create CheckTranslator objects in an ad-hoc fashion if there's only one kind of "translator". As long as the translator still depends on abstractions, which it does here, then maybe you shouldn't be injecting it at all, just let higher-level DI-enabled classes create them ad-hoc.