short story: I am trying to import, at runtime, a bunch of asmx services exposed from one server. I want to put those in one assembly and load it runtime. Everything is fine until i get to the moment where i compile the imported service descriptions as most of them have few classes that are multiplicated across the different service descriptions.
Some code:
static void Main(string[] args)
{
IEnumerable<ServiceData> services = GetServices();
List<CodeCompileUnit> codeCompileUnits = new List<CodeCompileUnit>();
foreach (ServiceData service in services)
{
Console.WriteLine($"Doing {service.Name.ToUpper()}");
WebClient webClient = new System.Net.WebClient();
webClient.Credentials = new NetworkCredential("username", "password", "domainname");
System.IO.Stream stream;
try
{
stream = webClient.OpenRead($"{service.Endpoint}?wsdl");
}
catch (WebException we)
{
Console.WriteLine(we.Message);
Console.WriteLine(we.InnerException?.Message);
continue;
}
ServiceDescription description = ServiceDescription.Read(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12"; // Use SOAP 1.2.
importer.AddServiceDescription(description, null, null);
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
CodeNamespace nmspace = new CodeNamespace($"Name.Space.{service.Name}");
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
try
{
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0) // If zero then we are good to go
{
codeCompileUnits.Add(unit1);
}
}
catch (InvalidOperationException ioe)
{
Console.WriteLine(ioe.Message);
Console.WriteLine(ioe.InnerException.Message);
}
}
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp" );
string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
CompilerParameters parms = new CompilerParameters(assemblyReferences);
parms.OutputAssembly = "Assembly.dll";
CompilerResults results = provider1.CompileAssemblyFromDom(parms, codeCompileUnits.ToArray());
if (results.Errors.Count > 0)
{
foreach (CompilerError oops in results.Errors)
{
Console.WriteLine("========Compiler error============");
Console.WriteLine(oops.ErrorText);
}
throw new System.Exception("Compile Error Occured calling webservice. Check Debug ouput window.");
}
else
{
Console.WriteLine("========Compiler error============");
Console.WriteLine(results.PathToAssembly);
Console.WriteLine(results.Output);
//ToDo: Add the compiled assembly
AppDomain.CurrentDomain.Load(results.CompiledAssembly.GetName());
}
var allTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(c => c.IsClass && c.Namespace != null && c.Namespace.Contains(@"Name.Space"))).Select(t => new { Name = t.Name, Namespace = t.Namespace });
//Assembly.GetExecutingAssembly().GetExportedTypes();
foreach (var s in allTypes)
Console.WriteLine($"{s.Namespace} => {s.Name}");
Console.ReadLine();
}
When I try to compile an assembly with
CompilerResults results = provider1.CompileAssemblyFromDom(parms, codeCompileUnits.ToArray());
I get few errors like this:
error CS0102: The type 'Name.Space.TypeNameGoesHere' already contains a definition for 'FielNameGoesHere'
So how do I force the compiler to ignore classes that are already in the namespace/assembly with the same name ?
Aucun commentaire:
Enregistrer un commentaire