I am working inside a public BLL with a number of different static methods. Inside a few of these methods, I need to display a certain string to the user depending on an ID# passed into the method. The situation is identical across these few methods. It's currently like this:
public class myBLL
{
public static addByID(int ID)
{
string myString = grabString(ID);
//do some stuff
Console.Writeline("You have added: " + myString);
}
public static removeByID(int ID)
{
string myString = grabString(ID);
//do some other stuff
Console.WriteLine("You have removed: " + myString);
}
public static grabString(int ID)
{
if(ID == 1)
return "string 1";
else
return "string 2";
}
}
I feel like I am violating DRY in myMethod1 and myMethod2 because why bother calling grabString twice? However I cannot come up with a way around this.
What about to use delegate for different parts of methods
public static void myGeneralMethod(int ID, Action<string> method )
{
string myString = grabString(ID);
method(myString);
Console.WriteLine(myString);
}
public static void SomeStuffForAdd(string myString)
{
}
public static void SomeOtherStuffRemove(string myString)
{
}
Or if you want to keep Add/Remove:
public static void removeByID(int ID)
{
myGeneralMethod(ID, SomeStuff);
}
It's a bit hard to evaluate what you really are looking for. But might I suggest some sort of logger? Or maybe a general class that store the value for later use?
public class myBLL
{
public static addByID(int ID)
{
//do some stuff
LogString("You have added: {0}", ID);
}
public static removeByID(int ID)
{
//do some other stuff
LogString("You have removed: {0}", ID);
}
public static LogString(string message, int ID)
{
string myString = "";
if(ID == 1)
myString = "string 1";
else
myString = "string 2";
Console.WriteLine(string.Format(message, myString);
}
}
To be honest, I would remove those static function and create a proper class.
public class MyObject
{
int ID;
public GetString()
{
if(ID == 1)
return "string 1";
else
return "string 2";
}
}
That way, the string could even be cached.
Related
Simply put how do you establish a connection between method variable decloration and connect it with class properties (or inner objects), lets say you have default or hard set values in a class like this (obviously they could be other types but for simplicity its set to strings) :
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
//think of it as a data layer where strings are pointers to dbSets
How do you leverage the same SampleClass in a method that allows ONLY pick of properties Method(property).
Easy sample that does what its supposed to:
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(string input)
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
var Test = new ProccessClass().Pick(new SampleClass().strB);
// we know this works and compiles and returns the strB
}
}
What would you have to convert to ommit the new instantiation and skip the class declaration (if possible but in theory should be doable)
new SampleClass().strB
needs to be just
strB
So how to get the final code to execute??
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(SampleClass sampleClass) //is it the variable declaration?
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
string Test = new ProccessClass().Pick(strB);
//so NO new keywords clean and easy set based on class provided above
}
}
Constructor and void setters but no go, the goal is to set the Hard relation ship between the method intake value and setters
I am trying to find the right design pattern for the below scenario.
I have a dataaccess class that can access different datasource. So I have designed to have an implementation class for each datasource(DataAccessMongo, DataAccesssql).
Based on the configuration change the data source must be switched. I believe the right way to do this is to use dependency injection and the data access class that have must accept an interface as a dependency. In the below scenario all the methods are static and I am unable to have a static method in an interface. So for now I am using a enum to check what is the data access type and call the corresponding method. If there are more data sources then definitely I should add more conditions for each data source. I would like a to arrive at a better design pattern. Please suggest what will be the best patter for this scenario. Thanks.
//Implementation class for Mongo
Public Class DataAccessMongo
{
public static string FindById(string itemId)
{
...
}
public static string FindByName(string itemId)
{
...
}
public static string FindByLastName(string itemId)
{
...
}
}
//Implementation class for Sql
Public Class DataAccessSql
{
public static string FindById(string itemId)
{
...
}
public static string FindByName(string itemId)
{
...
}
public static string FindByLastName(string itemId)
{
...
}
}
Public Class DataAccess
{
public static string FindById(string id)
{
string result = string.Empty;
if (databaseType == EnumDb.Mongo)
{
result = DataAccessMongo.FindById(id);
}
else if (databaseType == EnumDb.Sql){
result = DataAccessSql.FindById(id);
}
return result;
}
public static string FindByName(string itemId)
{
string result = string.Empty;
if (databaseType == EnumDb.Mongo)
{
result = DataAccessMongo.FindByName(id);
}
else if (databaseType == EnumDb.Sql){
result = DataAccessSql.FindByName(id);
}
return result;
}
public static string FindByLastName(string itemId)
{
string result = string.Empty;
if (databaseType == EnumDb.Mongo)
{
result = DataAccessMongo.FindByLastName(id);
}
else if (databaseType == EnumDb.Sql){
result = DataAccessSql.FindByLastName(id);
}
return result;
}
}
Note: These methods serve the web API methods.
Is it possible to give a C# Object like
public string Name
{
get { return _name; }
set { _name = value; }
}
a Method doing something like:
private void addTextToName(){
_name = _name + " - Test";
}
so that I can call it like
Name.addTextToName();
Because (where I come from) in JavaScript you can do such things with .prototype
Is there any way to do this in C#?
If you are asking can I add a method to a string? then yes. Look at extension methods.
public static string AddTextToName(this string s)
{
return s + " - Test";
}
Use it like this:
"Hello".AddTextToName();
Will return Hello - test.
Yes, there is a way for C# Objects (you used a string there, but though...).
Take a look at the so-called "extension methods" in C# as they are exactly what you need I think.
For further reference, look e.g. here: https://msdn.microsoft.com/en-us/library/vstudio/bb383977%28v=vs.110%29.aspx (the magic is in the this as parameter for the method)
Using the extension method.
class Program
{
static void Main()
{
Example e = new Example();
e.Name = "Hello World";
var x = e.Name;
var y = x.addTextToName();
Console.WriteLine(y);
Console.ReadLine();
}
}
class Example
{
public string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
public static class MyExtensions
{
public static string addTextToName(this string str)
{
return str += " - Test";
}
}
I'd like to know if there's a way to include a constructor and methods in an enum in C#. I had something like this in mind:
public enum ErrorCode
{
COMMONS_DB_APP_LEVEL("Application problem: {0}", "Cause of the problem"),
COMMONS_DB_LOW_LEVEL("Low level problem: {0}", "Cause of the problem"),
COMMONS_DB_CONFIGURATION_PROBLEM("Configuration problem: {0}", "Cause of the problem");
private String message;
private String[] argumentDescriptions;
private ErrorCode(String message, String[] argumentDescriptions)
{
this.message = message;
this.argumentDescriptions = argumentDescriptions;
}
public String[] GetArgumentDescriptions()
{
return argumentDescriptions;
}
public String GetKey()
{
return argumentDescriptions();
}
public String GetMessage()
{
return message;
}
}
Obviously, I cannot write an enum like this. How can I accomplish this?
That's not what enums are for. Use a class instead. Here's a quick example:
public class ErrorCode
{
public static readonly ErrorCode COMMONS_DB_APP_LEVEL = new ErrorCode("Application problem: {0}", "Cause of the problem");
public static readonly ErrorCode COMMONS_DB_LOW_LEVEL = new ErrorCode("Low level problem: {0}", "Cause of the problem");
public static readonly ErrorCode COMMONS_DB_CONFIGURATION_PROBLEM = new ErrorCode("Configuration problem: {0}", "Cause of the problem");
private String message;
private String[] argumentDescriptions;
private ErrorCode(String message, params String[] argumentDescriptions)
{
this.message = message;
this.argumentDescriptions = argumentDescriptions;
}
public String[] GetArgumentDescriptions()
{
return argumentDescriptions;
}
public String GetKey()
{
// Need to implement this yourself
}
public String GetMessage()
{
return message;
}
}
Console.WriteLine(ErrorCode.COMMONS_DB_APP_LEVEL.GetMessage(), "Foo");
// Application problem: Foo
A few more suggestions:
Names like COMMONS_DB_APP_LEVEL do not conform to Microsoft's General Naming Conventions.
You should generally use properties rather than methods like GetMessage (Unless your method takes a long time to execute or involves side effects).
You should be careful about returning the array from GetArgumentDescriptions as it allows other code to directly set any elements of the array (even though they can't directly assign a new array). Consider using something like Array.AsReadOnly.
You need to simply use the class and create the enum inside the class and also use the description if you want for every enum value.
public class ErrorCode
{
public enum ErrorCode
{
[Description("Application level problem")]
COMMONS_DB_APP_LEVEL,
[Description("Database level problem")]
COMMONS_DB_LOW_LEVEL,
[Description("Configuration level problem")]
COMMONS_DB_CONFIGURATION_PROBLEM
}
private String message;
private String[] argumentDescriptions;
private ErrorCode(String message, String[] argumentDescriptions)
{
this.message = message;
this.argumentDescriptions = argumentDescriptions;
}
public String[] GetArgumentDescriptions()
{
return argumentDescriptions;
}
public String GetKey()
{
return argumentDescriptions();
}
public String GetMessage()
{
return message;
}
}
because you must use classes instead of enums for writing code something like that. if you are more information for enums you can visit this link.
I've trying to achieve something like this:
class App {
static void Main(string[] args) {
System.Console.WriteLine(new Test("abc")); //output: 'abc'
System.Console.ReadLine();
}
}
I can do this passing by an variable:
class Test {
public static string str;
public Test (string input) { str = input; }
public override string ToString() {
return str;
}
}
works fine.
But, my desire is do something as:
class Test {
public static string input;
public Test (out input) { }
public override string ToString() {
return input;
}
}
System.Console.WriteLine(new Test("abc test")); //abc test
Don't works.
How I do this?
Thanks,advanced.
You can't. The variable approach is exactly the correct way, although the variable shouldn't be declared static, and shouldn't be a public field.
class Test {
public string Input {get;set;}
public Test (string input) { Input = input; }
public override string ToString() {
return Input;
}
}
I have an impression that you're not entirely understand what out keyword means. Essentially when you're writing something like void MyMethod(out string var) it means you want to return some value from method, not pass it into method.
For example there's bool Int32.TryParse(string s, out int result). It parses string s, returns if parse was successful and places parsed number to result. Thus, to correctly use out you should have real variable at the calling place. So you can't write Int32.Parse("10", 0) because this method can't assign result of 10 to 0. It needs real variable, like that:
int result;
bool success = Int32.TryParse("10", out result);
So, your desire is somewhat else - it is not in line with language designer's intentions for out :)