Ejemplo n.º 1
0
        public DALBuilderContext ConvertRunContext(RunContext runContext)
        {
            // Attempt to load the specified library
            if (!TryLoadAssembly(runContext.InputLibrary, out var coreAssembly))
            {
                throw new Exception($"Unable to load library: {runContext.InputLibrary}");
            }

            var coreTypeInfo = coreAssembly.DefinedTypes.Single(ti => ti.FullName.Equals(runContext.InputTypeName, StringComparison.InvariantCultureIgnoreCase));
            var coreType     = coreTypeInfo.UnderlyingSystemType;

            var dalContextDesc = new DALBuilderContext()
            {
                RootDataModelType = coreType,
                OutputDirectory   = runContext.OutputDirectory,
                OutputNamespace   = runContext.OutputNamespace
            };

            return(dalContextDesc);
        }
        public string EmitDataAccessLayerCode(DataModelPropertySheet dataModelPropertySheet, DALBuilderContext buildContext)
        {
            // 0: Class name (probably DM typename?)
            // 1: DataModel type name
            // 2: Namespace to house the DAL type
            // 3: TDataModel namespace
            const string baseTemplate =
                "using System;\n" +
                "using DataInspector.DataAccess.DAL;\n" +
                "using {3};\n\n" +
                "namespace {2} {{\n" +
                "\tpublic class {0} : ReflectiveDAL<{1}> {{\n" +
                "\t\tpublic {0}() : base() {{ }}\n" +
                "\t}}\n}}\n";

            var dataModelTypeName = buildContext.RootDataModelType.Name;
            var renderedTemplate  = string.Format(baseTemplate,
                                                  TypeUtility.GetClassNameFromType(buildContext.RootDataModelType),        // Class name
                                                  dataModelTypeName,
                                                  buildContext.OutputNamespace,
                                                  TypeUtility.GetUsingNamespaceForType(buildContext.RootDataModelType));

            return(renderedTemplate);
        }
        private static string GenerateCodeFrom(DataModelPropertySheet dataModelPropertySheet, DALBuilderContext buildContext)
        {
            // 0: Class name (probably DM typename?)
            // 1: DataModel type name
            // 2: Ctor body
            // 3: DAL Function definitions
            // 4: Namespace to house the DAL type
            // 5: TDataModel namespace
            const string baseTemplate =
                "using System;\n" +
                "using DataInspector.DataAccess.DAL;\n" +
                "using {5};\n\n" +
                "namespace {4} {{\n" +
                "\tpublic class {0} : BaseDirectPropertyCallDAL<{1}> {{\n" +
                "\t\tpublic {0}() : base() {{\n" +
                "{2}" +
                "\t\t}}\n" +
                "{3}\n" +
                "\t}}\n}}\n";

            // 0: Normalized call chain as dict key
            // 1: Name of DAL function to call (use dalFnNameTemplate)
            const string ctorRegisterFnTemplate = "\t\t\tcallChainDispatchMap.Add(\"{0}\", {1});\n";

            // 0: Normalized call chain as dict key
            // 1: Name of DAL function to call (use dalArrayFnNameTemplate)
            const string ctorRegisterArrayFnTemplate = "\t\t\tcallChainArrayDispatchMap.Add(\"{0}\", {1});\n";

            // 0: "Friendly" call chain (complies to function naming rules)
            // 1: Root object type
            const string dalFnHeaderTemplate = "private object {0}({1} inputObject)";

            // 0: "Friendly" call chain (complies to function naming rules)
            // 1: Root object type
            const string dalArrayFnHeaderTemplate = "private object {0}({1} inputObject, int[] indicies)";

            // 0: Function name
            // 1: Call chain to getter
            // 2: Root object type
            const string dalArrayFnDefinitionTemplate =
                "\t\t{0} {{\n" +
                "\t\t\treturn inputObject.{1};\n" +
                "\t\t}}\n";

            // 0: Function name
            // 1: Call chain to getter
            // 2: Root object type
            const string dalFnDefinitionTemplate =
                "\t\t{0} {{\n" +
                "\t\t\treturn inputObject.{1};\n" +
                "\t\t}}\n";

            var dataModelTypeName = buildContext.RootDataModelType.Name;
            var ctorCode          = new StringBuilder();
            var functionBodies    = new StringBuilder();

            foreach (var cci in dataModelPropertySheet.CallChains)
            {
                var callChainFriendlyName = TypeUtility.GetFunctionNameFromCallChain(cci.CallChain);
                var dalLookupKey          = CallChainUtility.GetDALLookUpKey(cci);

                if (cci.IncludesArrayIndexer)
                {
                    var dalFnName = string.Format(dalArrayFnHeaderTemplate, callChainFriendlyName, dataModelTypeName);
                    var renderedCallChainTemplate = BuildArrayCallChainTemplate(cci, "indicies");

                    var ctorArrayRegisterCall = string.Format(ctorRegisterArrayFnTemplate, dalLookupKey, callChainFriendlyName);
                    ctorCode.Append(ctorArrayRegisterCall);

                    var dalFnBody = string.Format(dalArrayFnDefinitionTemplate, dalFnName, renderedCallChainTemplate);
                    functionBodies.Append(dalFnBody);
                }
                else
                {
                    var dalFnName        = string.Format(dalFnHeaderTemplate, callChainFriendlyName, dataModelTypeName);
                    var ctorRegisterCall = string.Format(ctorRegisterFnTemplate, dalLookupKey, callChainFriendlyName);
                    ctorCode.Append(ctorRegisterCall);

                    var dalFnBody = string.Format(dalFnDefinitionTemplate, dalFnName, cci.CallChain);
                    functionBodies.Append(dalFnBody);
                }
            }

            var functionDefinitionCodeBody = functionBodies.ToString();
            var ctorSetupCode = ctorCode.ToString();
            var code          = string.Format(baseTemplate,
                                              TypeUtility.GetClassNameFromType(buildContext.RootDataModelType),
                                              dataModelTypeName,
                                              ctorSetupCode,
                                              functionDefinitionCodeBody,
                                              buildContext.OutputNamespace,
                                              TypeUtility.GetUsingNamespaceForType(buildContext.RootDataModelType));

            return(code);
        }
        public string EmitDataAccessLayerCode(DataModelPropertySheet dataModelPropertySheet, DALBuilderContext buildContext)
        {
            var generatedCode = GenerateCodeFrom(dataModelPropertySheet, buildContext);

            return(generatedCode);
        }
        public void Driver_InvokeCallChain()
        {
            var derp = new Derp()
            {
                A1 = new Glorp()
                {
                    B1 = new Flerb()
                    {
                        T1 = "A1,B1,T1",
                        T2 = "A1,B1,T2"
                    },
                    T1  = "A1,T1",
                    AR1 = new[] { "derp", "glorp", "flerb" }
                },
                A2 = new Flerb()
                {
                    T1 = "A2,T1",
                    T2 = "A2,T2"
                },
                T1 = "T1"
            };

            var derp2 = new Derp2()
            {
                Name  = "level1",
                Nodes = new[] {
                    new Derp2()
                    {
                        Name  = "level2_1",
                        Nodes = new Derp2[] {
                            new Derp2()
                            {
                                Name = "level3_1"
                            }
                        }
                    },
                    new Derp2()
                    {
                        Name  = "level2_2",
                        Nodes = new Derp2[] {
                            new Derp2()
                            {
                                Name  = "level3_2",
                                Nodes = new Derp2[] {
                                    new Derp2()
                                    {
                                        Name = "level4_2"
                                    }
                                }
                            }
                        }
                    },
                }
            };

            DataModelCallChainBuilder <Derp2> dmccb = new DataModelCallChainBuilder <Derp2>();
            var ps            = dmccb.BuildPropertySheet();
            var dpcDalFactory = new DirectPropertyCallDALFactory <Derp2>();
            var context       = new DALBuilderContext()
            {
                Namespace = "DataInspectorNS"
            };

            using var dal = dpcDalFactory.CreateDataAccessLayer(ps, context);
            var output = dal.FetchValue <string>(derp2, "Nodes[1].Nodes[0].Nodes[0].Name");      // level4_2

            var start = DateTime.Now;

            for (var i = 0; i < 1000000; ++i)
            {
                dal.FetchValue(derp2, "Nodes[1].Nodes[0].Nodes[0].Name");      // level4_2
            }
            var end = DateTime.Now - start;

            Console.WriteLine(end);
        }