示例#1
0
        // メイン関数
        static void Main(string[] args)
        {
            FactoryIF fileFactory = new FactoryFile();
            FileIF    txtFile     = fileFactory.Create("hoge.txt");
            FileIF    xmlFile     = fileFactory.Create("hoge.xml");

            txtFile.Read();
            xmlFile.Read();

            return;
        }
        private string RenderFactoryImplementation(ClassDeclarationSyntax concreteClassDeclarationSyntax,
                                                   INamedTypeSymbol concreteClassTypeSymbol,
                                                   INamedTypeSymbol factoryInterfaceTypeSymbol,
                                                   string factoryName)
        {
            var fileName             = "{0}.Generated.cs".FormatWith(factoryName);
            var factoryInterfaceName = factoryInterfaceTypeSymbol.Name;

            var project = this.solution.Projects.Single(proj => proj.GetDocument(concreteClassDeclarationSyntax.SyntaxTree) != null);
            var typeDeclarationDocument = project.GetDocument(concreteClassDeclarationSyntax.SyntaxTree);
            var factoryGeneratorEngine  = new FactoryGeneratorEngine(project, this.templatePath);

            var usingsToFilterOut      = new[] { concreteClassTypeSymbol.ContainingNamespace.ToString() };
            var outerUsingDeclarations = FilterOutUsings(concreteClassDeclarationSyntax.FirstAncestorOrSelf <CompilationUnitSyntax>().Usings, usingsToFilterOut);
            var innerUsingDeclarations = FilterOutUsings(concreteClassDeclarationSyntax.FirstAncestorOrSelf <NamespaceDeclarationSyntax>().Usings, usingsToFilterOut);

            var factoryInterfaceMethods = GetSuitableFactoryInterfaceMethods(concreteClassTypeSymbol, factoryInterfaceTypeSymbol);

            var allContractMethodParameters = factoryInterfaceMethods.SelectMany(contractTypeMethod => contractTypeMethod.Parameters).ToArray();

            if (!factoryInterfaceMethods.Any())
            {
                throw new InvalidOperationException("The interface {0} has no suitable method returning any interface implemented by {1}. Please check if their is any.".FormatWith(factoryInterfaceTypeSymbol, concreteClassTypeSymbol));
            }

            var allConstructorParameters = factoryInterfaceMethods.Select(factoryMethod => SelectConstructorFromFactoryMethod(factoryMethod, concreteClassTypeSymbol))
                                           .SelectMany(selectedConstructor => selectedConstructor.Parameters).ToArray();
            var constructorParametersUsingSelfType   = allConstructorParameters.Where(p => p.Type.Name == factoryInterfaceTypeSymbol.Name).ToArray();
            var constructorParametersWithoutSelfType = allConstructorParameters.Except(constructorParametersUsingSelfType)
                                                       .ToArray();
            var injectedParameters = (from parameter in (IEnumerable <IParameterSymbol>)constructorParametersWithoutSelfType
                                      where !allContractMethodParameters.Any(contractMethodParameter => CompareParameters(contractMethodParameter, parameter))
                                      select parameter).Distinct(new ParameterEqualityComparer()).ToArray();

            var concreteClassName = GetXmlDocSafeTypeName(concreteClassTypeSymbol.ToString());
            var @namespace        = GetDeclarationNamespaceFullName(concreteClassDeclarationSyntax);

            var generateCodeArguments = new[] { new Value("\"DeveloperInTheFlow.FactoryGenerator\"", false), new Value(string.Format("\"{0}\"", this.version), true) };

            // Class attributes
            var classAttributes = concreteClassDeclarationSyntax.AttributeLists
                                  .SelectMany(al => al.Attributes).Where(attributeSyntax =>
            {
                var attributeName = attributeSyntax.Name.ToString();
                return(this.attributeImportList.Any(attributeName.Contains));
            })
                                  .Select(a =>
            {
                var lastIndex = a.ArgumentList.Arguments.Count - 1;

                var arguments = a.ArgumentList.Arguments.Select((arg,
                                                                 i) => new Value(arg.ToString(), i == lastIndex));
                return(Attribute.Create(a.Name.ToString(), arguments));
            })
                                  .Concat(new[]
            {
                Attribute.Create("global::System.CodeDom.Compiler.GeneratedCode", generateCodeArguments),
                Attribute.Create("global::System.Diagnostics.DebuggerNonUserCodeAttribute")
            }).ToArray();

            // Generic types of the factory
            var classGenericTypes = this.genericTypeBuilderService.Build(factoryInterfaceTypeSymbol.TypeParameters);

            // Constructor of the factory
            var constructor = this.constructorBuilderService.Build(concreteClassDeclarationSyntax, injectedParameters);

            // Fields of the factory
            var fields = this.fieldsBuilderService.Build(injectedParameters).ToArray();

            // Methods of the factory
            var methods = this.methodsBuilderService.Build(concreteClassTypeSymbol, fields, injectedParameters, factoryInterfaceMethods, factoryInterfaceName);

            // Interface of the factory
            var inherit = factoryInterfaceTypeSymbol.ToString();

            // The factory
            var factoryClass = new Class(classAttributes, concreteClassName, constructor, methods, fields, classGenericTypes, inherit, factoryName);

            // The file containing the factory
            var factoryFile = FactoryFile.Create(@namespace,
                                                 factoryClass,
                                                 innerUsingDeclarations.ToFullString(),
                                                 outerUsingDeclarations.ToFullString());

            object model = factoryFile;
            var    transformationScript = string.Format(@"{0}\{1}.tcs", Path.GetDirectoryName(this.templatePath), factoryFile.FactoryFor);

            // Execute the script associated to the template in order to adapt the model for the template whether it exists.
            if (File.Exists(transformationScript))
            {
                var json = JObject.FromObject(factoryFile);
                model = Transform(json, transformationScript);
            }

            // The result of the generator
            var factoryResult = factoryGeneratorEngine.Generate(fileName, typeDeclarationDocument.Folders, model, factoryFile.FactoryFor);

            var existingDocument = project.Documents.SingleOrDefault(doc => doc.Name.Equals(fileName, StringComparison.OrdinalIgnoreCase) && doc.Folders.SequenceEqual(typeDeclarationDocument.Folders));

            if (existingDocument != null)
            {
                UpdateDocument(existingDocument, factoryResult.Code);

                return(existingDocument.FilePath);
            }

            this.solution = factoryResult.Document.Project.Solution;

            var projectFolder = Path.GetDirectoryName(project.FilePath);

            if (projectFolder == null)
            {
                throw new InvalidOperationException("Cannot determines the folder path of the project.");
            }

            var generatedFileFolderPath = Path.Combine(projectFolder, string.Join(@"\", typeDeclarationDocument.Folders));
            var generatedFilePath       = Path.Combine(generatedFileFolderPath, factoryResult.Document.Name);

            return(generatedFilePath);
        }