我必须为客户生成账单,但根据他们居住的地方,账单包含几乎相同的数据,但它们的格式大不相同。我已经想到了几种方法来解决这个问题,例如:
public void GenerateBill(User user)
{
if(user.Location == "blah blah")
{
//Code specific to this location
}
else if (user.Location == "dah dah")
{
//Code specific to this location
}
}
上述方法似乎可以变得非常长,特别是当不同位置的新用户不断弹出时。我想做类似的事情:
public void GenerateBillForUserInBlah();
public void GenerateBilForUserInDah();
但上述情况似乎也会失控并成为维护的噩梦。
我的另一个想法是使用IGenerateBill
这样的界面,然后执行以下操作:
class UserInBlah : IGenerateBill
{
//Implement IGenerateBill members
}
但是在上面,我必须为每个用户创建一个类。我可能仍然需要做上述事情,但我认为如果Managed Extension Framework
在这里有用。有替代解决方案吗?主要问题是我在运行时之前不会知道用户的位置,因此我必须在运行时根据用户的位置调用正确的方法。
答案 0 :(得分:2)
当然,这种方法:
public interface IGenerateBill {}
比其他人更优雅和可扩展。是的,MEF可以帮助你。
MEF具有“部分元数据”概念。如果您不熟悉它,可以阅读here。
从概念上讲,MEF元数据允许您编写IGenerateBill
实现,包含例如国家/地区代码或区域设置。稍后,在运行时,您可以通过以下方式检索正确的实现:
[BillGenerator("en-us")]
public class EnUsGenerateBill : IGenerateBill {}
[BillGenerator("ru-ru")]
public class RuRuGenerateBill : IGenerateBill {}
[BillGenerator("de-de")]
public class DeDeGenerateBill : IGenerateBill {}
container.GetExports<IGenerateBill, BillGeneratorMetadata>().Single(export => export.Metadata.Locale == "en-us");
答案 1 :(得分:0)
您可以在每个返回您的位置名称
的类中拥有一个属性例如:
interface IGenerateBill
{
void GenerateBill();
string SupportedCountry { get; }
}
class UserInUs : IGenerateBill
{
//Implement IGenerateBill members
public void GenerateBill()
{
//generate bill
}
public string SupportedCountry
{
get { return "US"; }
}
}
class UserInRussia : IGenerateBill
{
//Implement IGenerateBill members
public void GenerateBill()
{
//generate bill
}
public string SupportedCountry
{
get { return "Russia"; }
}
}
客户端代码将是:
string country = //Get from user in runtime
var billGenerator = BillgeneratorFactory.ResolveAll().ToList().First
(x => x.SupportedCountry == country);
billGenerator.GenerateBill;