如何在静态类中删除依赖项?

时间:2014-09-10 10:21:48

标签: c# static-classes

我有一个静态类,其中我正在读取XML来构建字典。 现在,这个初始化是在静态构造函数中完成的。

为了测试这个Initialize方法,我必须以某种方式删除XML逻辑的读取,并给它一个XDocument进行测试,但不知道我该怎么做。

 internal static class MasterMnemonicsLookup
    {

        private static Dictionary<string, StateCoverageMnemonic[]> masterMnemonics = new Dictionary<string, StateCoverageMnemonic[]>();


        private static StateCoverageMnemonic[] stateCoverageMnemonics;



        static MasterMnemonicsLookup()
        {
            Initialize();
        }

        private static void Initialize()
        {
            var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
            var serializer = new XmlSerializer(typeof (MasterMnemonicsType));
            var model = (MasterMnemonicsType) serializer.Deserialize(resource.CreateReader());

            var stateCoverageMnemonicsList = new List<StateCoverageMnemonic>();
            foreach (var masterMnemonic in model.MasterMnemonics)
            {
                var stateCoverageMnemonicsXml = new List<StateCoverageMnemonic>();

                var excludedStates = RiskStates.None;
                StateCoverageMnemonic allStateCoverageMnemonic = null;
                foreach (var stateCoverageMnemonic in masterMnemonic.StateCoverageMnemonics)
                {
                    var state = stateCoverageMnemonic.StateCode;
                    if (!state.HasFlag(RiskStates.All))
                    {
                        excludedStates = excludedStates | state;
                        var mnemonic = stateCoverageMnemonic.Mnemonic;
                        var coverageCode = stateCoverageMnemonic.CoverageCode;
                        var stateCoverageMnemonicTemp = new StateCoverageMnemonic(state, mnemonic, coverageCode);
                        stateCoverageMnemonicsXml.Add(stateCoverageMnemonicTemp);
                    }
                    else
                    {
                        //// TODO: If All occurs twice should we throw an exception
                        allStateCoverageMnemonic = new StateCoverageMnemonic(state, stateCoverageMnemonic.Mnemonic, stateCoverageMnemonic.CoverageCode);
                    }
                }

                if (allStateCoverageMnemonic != null)
                {
                    stateCoverageMnemonicsXml.Add(new StateCoverageMnemonic(RiskStates.All ^ excludedStates, allStateCoverageMnemonic.Mnemonic, allStateCoverageMnemonic.CoverageCode));
                }

                stateCoverageMnemonicsList.AddRange(stateCoverageMnemonicsXml);
                masterMnemonics.Add(masterMnemonic.MasterMnemonic, stateCoverageMnemonicsXml.ToArray());
            }

            stateCoverageMnemonics = stateCoverageMnemonicsList.ToArray();
        }

        private static string GetResourceTextFile(string filename)
        {
            string result = string.Empty;

            using (Stream stream = typeof(MasterMnemonicsLookup).Assembly.GetManifestResourceStream("Geico.Applications.Business.CoverageApi.DomainLayer.DataLayer." + filename))
            {
                var streamReader = new StreamReader(stream);
                result = streamReader.ReadToEnd();
            }
            return result;
        }
    }

2 个答案:

答案 0 :(得分:2)

不建议以这种方式使用静态构造函数,并且您的场景是一个很好的示例。您可以使用接受XDocument的公共实例构造函数来尝试单例模式。 (您可以使用内部,但这会使单元测试更难)。这是一种简单的依赖注入形式。

对于测试,您的类的实例可以由测试框架使用测试XDocument简单地创建。

对于您的实时应用程序,可以通过容器类型初始化和保存类的静态实例,并且可以私下(在容器内)传递相应的XDocument。

答案 1 :(得分:0)

我同意Darious Vaughan-Scott

但是如果你想继续使用静态构造函数,你可能希望将加载逻辑放入一个单独的类中,这样可以更容易测试。

例如

      internal class MasterMnemonicsLoader
      {
        public void Load(
            XDocument resource,
            Dictionary<string, StateCoverageMnemonic[]> masterMnemonics,
            StateCoverageMnemonic[] stateCoverageMnemonics)
        {
            //Do the loading here

        }
    }

并且在Initialize方法中,您可以调用Load方法

 private static void Initialize()
 {
    var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
    var loader = MasterMnemonicsLoader();
    loader.Load(resource, masterMnemonics, stateCoverageMnemonics);