What is MyAssembly.XmlSerializers.dll generated for? - c#

I am working on a project which generates an assembly. I just noticed that an additional assembly *.XmlSerializers.dll is being generated. Why this file is auto generated and what it is used for?

In .NET implementation, the XmlSerializer generates a temporary assembly for serializing/deserializing your classes (for performance reasons). It can either be generated on the fly (but it takes time on every execution), or it can be pregenerated during compilation and saved in this assembly you are asking about.
You can change this behaviour in project options (tab Compile -> Advanced Compile Options -> Generate serialization assemblies, Auto or On, respectively). The corresponding element in the project file is GenerateSerializationAssemblies, for example, <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>.

FYI. The exact steps to stop the XmlSerializers.dll from being auto-generated are:
In VS, right-click your project file and select "Properties"
Click the "Build" tab
Change the "Generate serialization assembly" dropdown from "Auto" to "Off"
Rebuild and it will be gone

I think this is the JIT (Just in time) compilation of XML serialisers for performance reasons.
You get the same thing with RegEx instances using the RegexOptions.Compiled option turned on.
I'm no .NET CLR expert, sorry for lack of precise technical detail.

*.XmlSerializers.dll are generated using the Sgen.exe [XML Serializer Generator Tool]
See Sgen.exe on MSDN
Typically the Sgen.exe is used in Post Build events of Projects. See if your project has a post build event which generates the *.XmlSerializers.dll

The project only generates the project.XMLSerialisers.dll for web applications. For other applications you have to run sgen separately.

Related

Can multiple .vsix with VB/C# Diagnostic Analyzer/CodeFix/AutoUpdate cause performance issue?

I'm implementing a system that will implement code quality as part of in-house quality measures. I've structured the system in two possible ways of implementation as follows:
Implementation 1: (Already implemented)
An AutoUpdate extension (Stub)
C# CodeQualityPlugin (Roslyn C# Diagnostic Analyzer & Code Fix)
VB CodeQualityPlugin (Roslyn VB Diagnostic Analyzer & Code Fix)
The AutoUpdate feature checks for any update of itself and other CodeQuality plugins by verifying their version number. It halts update for the next 7 days once the CodeQuality plugins are updated.
This is presently my idea of implementation, but the development is halted citing the possible performance issue related to number of extensions in this implementation and that there might be a Visual Studio limitations in its usage/performance (as mentioned by the team)
Implementation 2: (Suggested)
C# CodeQualityPlugin (Roslyn C# Diagnostic Analyzer, Code Fix, AutoUpdate)
VB CodeQualityPlugin (Roslyn VB Diagnostic Analyzer, Code Fix, AutoUpdate)
In this the update functionality is individually triggered and maintains the single responsibility philosophy.
I'm not sure if the AutoUpdate project (Which uses the menu command template) and C#/VB CodeFix/DiagnosticAnalyzer project (Roslyn Template ) can co-exist?
Implementation 3: (One of the opinion)
CodeQualityPlugin (Roslyn C#/VB Diagnostic Analyzer, Code Fix, AutoUpdate)
I'm not even sure if these three can co-exists in a single vsix.
So my question what could be the performance issues in the above three scenarios, and how do we implement the plugin that we develop based on the Roslyn template into a normal menu command template extension for visual studio.
---EDIT---
To summarize the requirement was as follows
Coexistence: VSPackage extension (to extend shell command component of Visual Studio) and Managed Extensibility Framework/MEF extensions (to customize and extend the editor to include Roslyn DiagnosticAnalyzer/CodeFix), should coexist either in
Single VSIX
Maximum 2 VSIXs
Performance: The coexistence shouldn't affect the performance and AutoUpdate taken care by the VSPackage extension should not create redundant service calls.
No.
The only real "performance problem" you can have is putting the C# and VB ones in the same assembly (note, not VSIX), which would mean when we have to load one we load the others.
From the perspective of MEF, we just get a list of exports back: we don't know which VSIXes they're from, and it's hard to figure out if even if we wanted to. So which VSIX you put stuff in doesn't matter at all: divide them up based upon what makes sense for your users.
Caveats of Roslyn and VSIX packaging:
As mentioned by Srivatsn
Extensions that refer to both Microsoft.CodeAnalysis.CSharp and Microsoft.CodeAnalysis.VisualBasic will
Load both the compilers even if we try to open a C# project, this is not ideal.
If we have to analyze the symbols ISymbolAnalyzer,where you are analyzing just the symbols and not the syntax nodes, then we should adopt a single language-agnostic analyzer. This means we don't have to refer any C#/VB dlls (Even Microsoft is thinking about implementing more language-agnostic analyzer). Include two export attributes - one for each language, these attributes tell VS to instantiate and call these analyzers when the respective language is contained in the solution.
Compilation as a process leaves the memory after the compilation is done, but since there is a compilation happening at almost every keystroke and if the analyzer refers to both c# and VB, it will bring both compilers into memory. Since there is a persistence characteristic, it could be a problem if there is a large project under the solution (This is my typical production scenario)
There is a confusion whether the compiler is loaded when the respective syntax method is invoked or on instantiation of the exported analyzer (which is again being filter through the MEF export attribute by mentioning the respective language use case) since he also mentioned that the if a method that refers to both kind of syntax node might make the JIT compile and load the dlls.
Any analyzers linked to menu command would be VS specific and if they are linked to the project then it will participate in the build as well, even outside of the VS through MSBuild
VSIX should be able to export multiple components for extending both of those extension points.
As mentioned by VSadov
Persistence of the syntax tree data-structure and the need to re-do analysis at every keystroke(delta-compilation: this is what Srivatsn's compilation means) made them design the red-green tree method which helps in the performance of the delta-compilation.
As mentioned by SLaks
MEF exports doesn't make any difference whether they are packaged in a single VSIX or not (but it should be noted that there is a performance issue related to combining both type analyzers into a single assembly which is an MEF export)
As mentioned by Kevin Pilch
Although it doesn't matter where these assemblies are packaged in unless they are separate in concern when it comes to language specific references.
Virtual memory will be reserved if the analyzer references both the C# and VB specific Roslyn assemblies and these compiler assemblies are large
The performance problems being Disk loading and JIT costs (I'm not sure how there is a JIT cost if there is no compilation and only reference in it), but since there is an address space reserved there could be an issue in VS (I'm not sure how that will be an issue.)
What Microsoft does, according to him, is to create three projects to deal with this (According to Srivatsn Microsoft is still trying for language-agnostic analyzers)
Shared (No language specific binaries in it)
C# specific (+ shared libraries)
VB Specific (+ shared libraries)
If no language specific binaries are referred and if the MEF exports are appropriately attributed with ContentType or LanguageName then the above issue can be solved
We can bundle additional assemblies into a single VSIX (by embedding the other project in it) and VS will load each independently
Final Implementation:
So Finally I came to a conclusion after discussion with my team as follows
A single VSIX implementation by embedding the following projects in it
Update plugin
Checks if update was present in the past 7 days
Then checks for the version number of the Plugin from server side via a JSON request
Then downloads the plugin from the server, stores the download date in VS settings for initial check
Disables the previous plugin
Uninstalls the previous plugin
Installs the new plugin
This functionality is triggered when
The VS loads
Manual menu command (which should override the download date check)
C# plugin
Implements and refers only rules for C#
VB Plugin
Implements and refers only rules for VB

how to put language resources in a separate project to generate satellite assemblies

I've been using http://www.codeproject.com/Articles/30035/Simple-WPF-Localization project to localize an app because (well) it's simple and straight-forward and supports dynamic language change.
I put all the language resources in the main project (i.e. resources.resx, resources.ja-JP.resx). That way the satellite assemblies get generated automatically and into the correct folder structure.
However, i would like to put all the language resources (except the default/neutral one - resources.resx) in a separate project. With that, i don't need to rebuild the main project (which has the application source) if i only needed to change something in one of the translations.
So, i would like to know if there is a standard way (or at least a very straight-forward way) of creating a VS project that only contains language resources.
I already tried creating an empty project and setting the output to class-library and the assembly to match my executable's name. It does create the correct satellite assemblies in the correct folder but it also generates a dll. It would be real simple if there's a project-type for c# or wpf that are completely language resource-only but i can't seem to find any references about it.
(btw, i'm using VS 2010 with WPF project)
thanks for any help!
(late reply, but for the community)
Depending on exactly what one want to achieve, building satellite assemblies from the command line might be the ticket for you (using command line tools resgen and al.exe).
I had to do this to enable non developers to modify resources, and without going through the development team/build/deploy cycle, have their changes take effect and allow them to validate.
This is mentioned in a lot of places in the MSDN docs, but I haven't seen many end-to-end samples demostrating it:
https://github.com/JohanPGunnarsson/LocalizedResx

VimService() initialization is too slow [duplicate]

I'm doing some experiments with Microsoft Dynamics CRM. You interact with it through web services and I have added a Web Reference to my project. The web service interface is very rich, and the generated "Reference.cs" is some 90k loc.
I'm using the web reference in a console application. I often change something, recompile and run. Compilation is fast, but newing up the web service reference is very slow, taking some 15-20 seconds:
CrmService service = new CrmService();
Profiling reveals that all time is spent in the SoapHttpClientProtocol constructor.
The culprit is apparently the fact that the XML serialization code (not included in the 90k loc mentioned above) is generated at run time, before being JIT'ed. This happens during the constructor call. The wait is rather frustrating when playing around and trying things out.
I've tried various combinations of sgen.exe, ngen and XGenPlus (which takes several hours and generates 500MB of additional code) but to no avail. I've considered implementing a Windows service that have few CrmService instances ready to dish out when needed but that seems excessive.
Any ideas?
The following is ripped from this thread on the VMWare forums:
Hi folks,
We've found that sgen.exe does work. It'just that there is a couple of additional steps beyond pre-generating the serializer dll's that we missed in this thread. Here is the detailed instruction
PROBLEM
When using the VIM 2.0 SDK from .NET requires long time to instantiate the VimService class. (The VimService class is the proxy class generated by running 'wsdl.exe vim.wsdl vimService.wsdl')
In other words, the following line of code:
_service = new VimService();
Could take about 50 seconds to execute.
CAUSE
Apparently, the .NET XmlSerializer uses the System.Xml.Serialization.* attributes annotating the proxy classes to generate serialization code in run time. When the proxy classes are many and large, as is the code in VimService.cs, the generation of the serialization code can take a long time.
SOLUTION
This is a known problem with how the Microsoft .NET serializer works.
Here are some references that MSDN provides about solving this problem:
http://msdn2.microsoft.com/en-us/library/bk3w6240.aspx
http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializerassemblyattribute.aspx
Unfortunately, none of the above references describe the complete solution to the problem. Instead they focus on how to pre-generate the XML serialization code.
The complete fix involves the following steps:
Create an assembly (a DLL) with the pre-generated XML serializer code
Remove all references to System.Xml.Serialization.* attributes from the proxy code (i.e. from the VimService.cs file)
Annotate the main proxy class with the XmlSerializerAssemblyAttribute to point it to where the XML serializer assembly is.
Skipping step 2 leads to only 20% improvement in the instantiation time for the VimService class. Skipping either step 1 or 3 leads to incorrect code. With all three steps 98% improvement is achieved.
Here are step-by-step instructions:
Before you begin, makes sure you are using .NET verison 2.0 tools. This solution will not work with version 1.1 of .NET because the sgen tool and the XmlSerializationAssemblyAttribute are only available in version 2.0 of .NET
Generate the VimService.cs file from the WSDL, using wsdl.exe:
wsdl.exe vim.wsdl vimService.wsdl
This will output the VimService.cs file in the current directory
Compile VimService.cs into a library
csc /t:library /out:VimService.dll VimService.cs
Use the sgen tool to pre-generate and compile the XML serializers:
sgen /p VimService.dll
This will output the VimService.XmlSerializers.dll in the current directory
Go back to the VimService.cs file and remove all System.Xml.Serialization.* attributes. Because the code code is large, the best way to achieve that is by using some regular expression substitution tool. Be careful as you do this because not all attributes appear on a line by themselves. Some are in-lined as part of a method declaration.
If you find this step difficult, here is a simplified way of doing it:
Assuming you are writing C#, do a global replace on the following string:
[System.Xml.Serialization.XmlIncludeAttribute
and replace it with:
// [System.Xml.Serialization.XmlIncludeAttribute
This will get rid of the Xml.Serialization attributes that are the biggest culprits for the slowdown by commenting them out. If you are using some other .NET language, just modify the replaced string to be prefix-commented according to the syntax of that language. This simplified approach will get you most of the speedup that you can get. Removing the rest of the Xml.Serialization attributes only achieves an extra 0.2 sec speedup.
Add the following attribute to the VimService class in VimService.cs:
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]
You should end up with something like this:
// ... Some code here ...
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]
public partial class VimService : System.Web.Services.Protocols.SoapHttpClientProtocol {
// ... More code here
Regenerate VimSerice.dll library by
csc /t:library /out:VimService.dll VimService.cs
Now, from your application, you can add a reference to VimSerice.dll library.
Run your application and verify that VimService object instanciation time is reduced.
ADDITIONAL NOTES
The sgen tool is a bit of a black box and its behavior varies depending on what you have in your Machine.config file. For example, by default it is supposed to ouptut optimized non-debug code, but that is not always the case. To get some visibility into the tool, use the /k flag in step 3, which will cause it to keep all its temporary generated files, including the source files and command line option files it generated.
Even after the above fix the time it takes to instantiate the VimService class for the first time is not instantaneous (1.5 sec). Based on empirical observation, it appears that the majority of the remaining time is due to processing the SoapDocumentMethodAttribute attributes. At this point it is unclear how this time can be reduced. The pre-generated XmlSerializer assembly does not account for the SOAP-related attributes, so these attributes need to remain in the code. The good news is that only the first instantiation of the VimService class for that app takes long. So if the extra 1.5 seconds are a problem, one could try to do a dummy instantiation of this class at the beginning of the application as a means to improve user experience of login time.
You might wish to look into the Sgen.exe tool that comes with .NET. There's also a handy little thing in Visual Studio's C# project properties "Build" page, at the very bottom, called "Build serialization assembly" that automatically runs Sgen for you.
I believe that this is not an SGEN issue. I have looked at the constructor code, and I see that it is doing a lot of reflection (based on the XmlIncludeAttribute on the class). It reflects on all of them, and can take a really long time.
There is a pre-generated XmlSerializer assembly that comes with CRM. Check to see whether you have SdkTypeProxy.XmlSerializers.dll and SdkProxy.XmlSerializers.dll in the GAC.
If you don't then that means that when you create the CrmService, .net will generate the XmlSerializer assembly which can take some time.
Hope this helps
I came across this thread when trying to find out why my initial SoapHttpClientProtocol calls were taking so long.
I found that setting the Proxy to null/Empty stopped the Proxy AutoDetect from occurring - This was taking up to 7 seconds on the initial call:
this.Proxy = GlobalProxySelection.GetEmptyWebProxy();
I have used above detailed answer as guide, and went a few steps forward, making a script to automate process. Script is made out of two files :
generateproxy.bat :
REM if your path for wsdl, csc or sgen is missing, please add it here (it varies from machine to machine)
set PATH=%PATH%;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools;C:\Program Files (x86)\MSBuild\14.0\Bin
wsdl http://localhost:57237/VIM_WS.asmx?wsdl REM create source code out of WSDL
PowerShell.exe -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'" REM proces source code (remove annotations, add other annotation, put class into namespace)
csc /t:library /out:references\VIM_Service.dll VIM_WS.cs REM compile source into dll
sgen /p references\VIM_Service.dll /force REM generate serializtion dll
generateproxy.ps1
(Get-Content VIM.cs) |
ForEach-Object {
$_ -replace "(?<attr>\[global::System.Xml.Serialization.[^\]]*\])", "/*${attr}*/" `
-replace "public partial class VIM", "[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = ""VIM_Service.XmlSerializers"")] `npublic partial class VIM" `
-replace "using System;", "namespace Classes.WS_VIM { `n`nusing System;"
} |
Set-Content VIM.cs
Add-Content VIM.cs "`n}"
I have added those two files to client project, and in the pre-build event I have added lines
cd..\..
generateproxy
So, before every build, proxy classes are regenerated, and developer has (almost) no need to think about it. While building, WS must be up and running, and its URL must be in bat file. As a result of prebuild, two dll files will regenerate in client project's subfolder references.
After first execution of scripts, you should add reference to new dll.

Compile CSProj in Visual Studio with /CLR:Safe? Fatal Error LNK1302: only support linking safe .netmodules

So I am having an issue converting an opensource project (SQLite) to use a different build system and now I'm having trouble linking projects. Essentially I have a VCProj file that has a definition like this:
<Tool
Name="VCLinkerTool"
AdditionalOptions="/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp
/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp
/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp"
AdditionalDependencies="..\System.Data.SQLite\bin\System.Data.SQLite.netmodule"
OutputFile="..\bin\System.Data.SQLite.DLL"
GenerateManifest="false"
IgnoreDefaultLibraryNames=""
ModuleDefinitionFile="src\sqlite3.def"
EmbedManagedResourceFile=""
DelayLoadDLLs="advapi32.dll"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary=""
KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
CLRUnmanagedCodeCheck="true"
/>
And I am unable to properly link the System.Data.SQLite.netmodule due to the following error:
Linking...
4>..\System.Data.SQLite\bin\System.Data.SQLite.netmodule : fatal error LNK1302: only support linking safe .netmodules; unable to link pure .netmodule
And the System.Data.SQLite.netmodule is generated from a C#/.NET project. How is it I can force it to compile with the /clr:safe option since according to MSDN this is the way to fix the issue. The problem is is that I don't know how to compile it with /clr:safe. How is it I can do that in the csproj file or in visual studio somewhere? If I am off base in my attempts to fix this please let me know a better way.
UPDATE:
So I have determined the issue but I'm not sure why it is an issue. So the interop project (the C project which compiles the sqlite code and links) uses the VCLinkerTool to link to the System.Data.SQLite.netmodule. There is then a C# project that creates the System.Data.SQLite.netmodule using the following command (Anything in {} was added to reduce length):
C:\Windows\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /unsafe- /nowarn:1701,1702 /platform:AnyCPU /errorreport:prompt /doc:..\bin\System.Data.SQLite.XML {DLL REFEERENCFES /debug- /filealign:512 /optimize+ /out:obj\Release\System.Data.SQLite.netmodule {RESOURCES AND CS FILES}
The problem is with the /platform:AnyCPU. In my build it is /platform:x86 and for some reason this causes issues when linking and I'm not sure why but this is what I have narrowed it down to since I can change it to AnyCPU and it will build and link properly. Any insight on this is appreciated.
Ok so I finally narrowed down what the issue was and maybe someone can spread some more light onto why that is but I have a rough idea why. Basically you can't have the VCLinkerTool link to .netmodules that were created targetting the /platform:x86 (and I assume any other variant that isn't AnyCpu. I would assume this has to do with the way that the linking occurs internally when linking the mixed mode dll with a .netmodule. So it looks like for this to work you have to have your C# project compiled with /platorm:AnyCpu.
This may be what you are looking for:
To set this compiler option in Visual Studio
1.
In Solution Explorer, right-click the project name, and then click Properties to open the project Property Pages dialog box.
2.
Select the Configuration Properties folder.
3.
On the General property page, modify the Common Language Runtime support property.
Note
When /clr is enabled in the Property Pages dialog box, compiler option properties that are not compatible with /clr are also adjusted, as required. For example, if /RTC is set and then /clr is enabled, /RTC will be turned off.
Also, when you debug a /clr application, set the Debugger Type property to Mixed or Managed only. For more information, see Project Settings for a C++ Debug Configuration.
For information about how the create a module, see /NOASSEMBLY (Create a MSIL Module).
You would have to edit the CSProj to not use features that cause the code to no longer be safe. These are easy to spot -- anywhere where you're using P/Invoke, or anywhere where there's an unsafe code block, that code is not safe. If any of the code in your assembly is unsafe, the whole assembly gets marked as unsafe.
If you remove the unsafe code the resultant assembly will automatically be safe.
(In the case of SQLite I believe this will be impossible, because SQLite is a C library, which cannot be compiled as safe)

Build entire solution but add global Conditional Compilation Symbols for just one project

I hava a quite complex solution, containing 10 projects aside from Test projects.
It is a network of distributed applications & services that communicate using remoting; therefore having the proper referenced assemblies (& versions) is crucial. That's why I want the whole thing to be compiled and schrink-wrapped in ONE build.
One of the applications is a demo/analysis-tool that runs a subprocess of another - much bigger - application based on the user's input and displays the results; That way engineers have a tool to help tweak their settings for "the big computation". Obviously that subprocess is contained in another assembly, and a big part of te results presented to the engineers is generated by
#if ENABLE_TRACE_MATCHING
Trace.WriteLine("Some engineering output");
#endif
My problem is that Conditional Compilation Symbols in the project settings are limited to that project's assembly, and do not propagate over referenced assemblies.
How can I configure my build in such a way that all projects will be built without ENABLE_TRACE_MATCHING being defined, except for the one debug/analysis-app project where all referenced projects/assemblies must be compiled with ENABLE_TRACE_MATCHING being defined
I also cannot replace #if ENABLE_TRACE_MATCHING by #if DEBUG, since that would enable a whole lot of different output our engineers wouldn't know how to handle.
Thanks in advance.
PS: If you think my code smells, then I agree. Additionally: It's mostly not my code ;)
You need to learn more about Microsoft Build, which is an out-of-the-box Microsoft .NET tool present in any framework's installation.
Using MSBuild you can define these "symbols" (properties) and a batch of commands (targets).
That's you can create a MSBuild script that imports default Visual Studio targets from all projects in your solution, and declare in the script these properties ("symbols").
In fact, the property to set such symbols already exists: "DefineConstants".
So, since you have it, you can have that MSBuild script that provides that property value, re-declaring it there, so, ALL MSBuild targets will be knowing about these symbols.
EDIT:
Check this other question too:
msbuild, defining Conditional Compilation Symbols

Categories

Resources