I have a class in one application - that I cannot change (legacy) - that is inside of a assembly (DLL file):
public class ShippingMethod
{
public string ShipMethodCode { get; set; }
public string ShipMethodName { get; set; }
public decimal ShippingCost { get; set; }
public List<ShippingMethod> GetAllShippingMethods()
{
......
}
}
I have a second application that is referencing that assembly (DLL file) and needs to populate a drop-down with all the Shipping Methods. Ex: "UPS - $3.25"
The issue is that it needs to be using the correct format for different currencies. Ex: $3.25 or 3.25€ depending on a parameter called CountryID.
I have written a function String DisplayMoney(Decimal Amount, Integer CountryID) that will return the correct format of the amount.
Now I need to apply this function to every shipping method and save it into a new list.
What is the best way to do this?
I can create another class called LocalizedShippingMethods as follows:
public class LocalizedShippingMethod
{
public ShippingMethod ShipMethod { get; set; }
public string LocalizedShippingCost { get; set; }
}
Is this the best way to accomplish this? Is there a better way to do this using inheritance? And if I use inheritance, how do I get the values from the first LIST into the NEW LIST?
That is indeed a good method of doing it. You can use a pretty quick Linq query to pull the old List into the new one:
List<LocalizedShippingMethod> Translate(List<ShippingMethod> oldList)
{
return oldList.Select(a => new LocalizedShippingMethod
{
// Initialize properties according to however you translate them
}).ToList();
}
Additionally, to make this more streamlined and obvious, you could do any of the following to aid in the translation:
Create a constructor for LocalizedShippingMethod that takes in a ShippingMethod and properly sets the properties
Create a static method on LocalizedShippingMethod that takes in a ShippingMethod and returns an initialized LocalizedShippingMethod
Create an operator on LocalizedShippingMethod that converts from a ShippingMethod
Create an extension method on ShippingMethod, call it ToLocalized() that returns a LocalizedShippingMethod
What if you create an extension method for the ShippingMethod class?
The best way to do this is whatever way works best for you. If you're the person who's going to have to maintain this code, what will make your life the easiest down the road?
Once you've answered that question, that is the best solution.
Related
I have an parent class and two child like these:
public class Parent {
public Guid Id { get; set; }
public string Name { get; set; }
}
public class FirstChild {
public string IdentityCode { get; set; }
}
public class OtherChild {
public string RegistrationCode { get; set; }
}
There is a question: Is it a good approach to store these two inherited classes in the same Index inside ElasticSearch?
I see there is a _type property that is added to my docs after they are stored in DB but it has always "doc" value.
I test this code to fill it but it seems it is not working this way.
await ElasticClient.IndexAsync<FirstChild>(child, m => m.Index(IndexName));
And Also, I found this question on SO for retrieving my entries from DB but it is outdated and the API is changed and no more accessible.
I want to know if it is a good approach to store sibling data in the same index how can I do this properly.
As of ES 6.0, it is not possible anymore to store multiple types inside the same index, i.e. the _type field you're referring to will always be either doc or _doc. In ES 8.0, the _type field will be removed altogether.
However, if it makes sense for your use case, you can still decide to store several types inside a single index using a custom type field that is present in your document.
You should strive to only store in the same index data that share the same (or very similar) mapping, which doesn't seem to be the case for Parent, FirstChild and SecondChild, but if you add a public string type property to your classes you can still do it.
First of all, apologies if I posted it in the wrong place, I'm new here and I'm not sure if I posted in the right place.
Well, I'm trying to build a generic search method, where I'll add search parameters to mount a SQL Query and execute it on the database. All that using C#. My goal is that the parameter corresponding to the field I'll search, to be a property of the class the method is in. For example:
public foo
{
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public void AddSearchParameter(???, EnumOperator Operator, object Value)
}
Whenever I want to specify a parameter to add on the search, I would like it to look like this:
foo xxx = new foo();
xxx.AddSearchParameter(foo.CustomerCode, EnumOperator.Equal, txtCustomerCode.text);
My question is how to do it?
If you are trying to pass the member information (so that the AddSearchParameter can inspect the MemberInfo and write suitable SQL), then you'd need to use either a string literal (i.e. "CustomerCode"), or an expression tree. The latter is richer, but involves learning the Expression<T> API. But fundamentally:
public void AddSearchParameter(Expression<Func<object>> expression, ...)
...
xxx.AddSearchParameter(() => foo.CustomerCode, ...)
This, however, is not a trivial area of .NET.
If I were doing something like this, I would probably make the Search() method on foo check for the existence of values in the various this properties, and then build the query based on that.
public List<Results> Search()
{
if (!String.IsNullOrEmpty(this.CustomerCode))
{
// add search value to query
}
// etc.
}
Here is some code that uses a parameter class to contain the possible parameters to the Show() method. The values in this FooOption class aren't very related. You can see this by looking at the implementation of Show() below. I know this is bad code, but are there any anti-patterns related to doing this?
class FooOptions {
public int? Id { get; set; }
public string BazContext { get; set; }
public int? BazId { get; set; }
}
class BarMgr {
public Bar Show(FooOptions options) {
if (options == null)
options = new FooOptions();
if (options.Id.HasValue)
return svc.GetBar(options.Id.Value);
if (!string.IsNullOrEmpty(options.BazContext) && options.BazId.HasValue)
return svc.GetBar(options.BazContext, options.BazId.Value);
return null;
}
}
Update:
I know that parameter objects are not an anti-pattern. In my experience, parameter object properties are related. This is the possible anti-pattern that I am trying to locate. setting all three properties makes no sense.
After your update, here my answer:
As far as I know, there is no real name for an anti-pattern like this, but there is at least one principle that this method violates:
The Single-Responsibility-Principle.
And it really is a problem of the method and not of the parameter object.
It's called the parameter object pattern, and it's not considered an antipattern -- it's a good way to deal with methods that would otherwise have too many parameters.
There might be an anti-pattern if you use options a lot we have something called feature envy and is an indication that you might want to move functionality into the actual feature being used.
I haven't used LINQ extensively but the more I use it the more I realize how powerful it can be. Using the LinqDataSource.OrderBy clause is obviously easy if you want to sort from a property on the bounded items but what if you want to sort the items based on a method return? Take this class for instance (please ignore the quirky design - it's just used to emphasize my point):
public class DataItem
{
private string Id { get; set; }
private int SortValue { get; set; }
public DataItem(string id, int sortValue)
{
this.Id = id;
this.SortValue = sortValue;
}
public int GetSortValue()
{
return SortValue;
}
}
Is there a way that I can set the orderby expression on the LinqDataSource so that it uses the value returned from GetSortValue (i.e order by other members than properties) but without altering the DataItem class?
If the method has no parameters you could wrap it with a property?
public int SortOrderBy { get { return GetSortValue(); } }
Edit: This will also work if the parameters are constants or class fields/properties.
The MSDN docs mention that it is indeed possible to do custom sorting but I might have misinterpreted your question.
Im trying to implement multi-language support in my system,
the other systems at work uses xmlfiles for this generated from a database that they have used for some time now so they want me to use this aswell.
I have managed to translate everything except the displaynames in my formmodels, these values can apperantly only be constant values so i can't use a method that gets the correct translation.
This is how the code is now:
[System.ComponentModel.DisplayName("Kontraktnamn")]
public string Name { get; set; }
And i want to do something like this:
[System.ComponentModel.DisplayName(GetTextByKey("Contract_Name"))]
public string Name { get; set; }
Is it possible to work around this? Or maybe there is a better way to do it and still use the xmlfiles?
You'll need to create your own custom attribute that can read the xml values:
public class CustomDisplayName : DisplayNameAttribute
{
public CustomDisplayName()
{
this.DisplayName = MyXmlReader.Read(DisplayName);
}
}