如何动态解析类

时间:2012-10-05 05:12:37

标签: c# design-patterns .net-4.0 mef

我必须为客户生成账单,但根据他们居住的地方,账单包含几乎相同的数据,但它们的格式大不相同。我已经想到了几种方法来解决这个问题,例如:

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在这里有用。有替代解决方案吗?主要问题是我在运行时之前不会知道用户的位置,因此我必须在运行时根据用户的位置调用正确的方法。

2 个答案:

答案 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;