📜 ⬆️ ⬇️

Incredible Adventures with Microsoft.Practices.Unity

It will be a question not of opportunities and delicacies of use of AOP, and about one personal case of use of Unity in the project.

A bit of background


For the needs of auto-update of several client applications, its own library was written, which checks for updates and performs updates in a separate thread. Library usage on clients is minimized.

Actually the story


And so, at one point, after applying the next update. A distant client in Omsk began to experience strange “brakes” when launching our application. The program hung for about 30-40 seconds, then it started successfully and later worked with the usual speed.
Hmm ... I began to watch the code.

There is a class implemented as a singleton:
')
private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  1. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  2. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  3. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  4. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  5. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  6. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  7. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  8. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  9. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  10. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  11. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  12. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  13. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  14. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
  15. private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .
private static readonly UpdateManager instance = new UpdateManager(); /// /// ( ). /// Main(). static UpdateManager() { } private UpdateManager() { } public static UpdateManager Instance { get { return instance; } } * This source code was highlighted with Source Code Highlighter .


There is a call from the client application:

  1. UpdateManager.Instance.InitializeNotifyIconForm ();
* This source code was highlighted with Source Code Highlighter .


So here, when you call, there is an incomprehensible lag, in 30 seconds ,. determined by tracing
Workplace Information: 0: Start the execution of the Workplace.Workplace.InitializeNotifyIcon method. The current time: 12/09/2011 14: 15:48

Krista.FM.Client.Workplace Information: 0: Workplace.Workplace.InitializeNotifyIcon method completed successfully. Elapsed time - 30154 ms. The time now is: 09.12.2011 14: 16:18

Those. static fields must be initialized before the first call, and accordingly, the constructor must be called. But as shown by further research, the first call to the designer occurred only after 30 seconds.

Framework Information: 0: Start execution of the Framework.UpdateManager..ctor method Current time: 12/09/2011 14: 16:18

Question: what is being done at this time?


He began to remember that such a new one appeared, which can cause brakes. I remembered that I started using the Microsoft.Practices.Unity library.

It turns out this library has a digital signature.

During the initialization of the application. NET Common Language Runtime (CLR) checks for signed assemblies whether a certificate has been revoked. This naturally requires access to the Internet. If the server is unavailable, for example, due to a firewall or lack of network connectivity, the CLR eventually timed out, this can take from 15 to 30 seconds.

Possible solutions that were found on the net.

Infragistics solution .

1. Configure the firewall, give the user the Internet. Immediately disappears, a lot of customers, they are usually denied their rights.
2. Disable the option Internet Explorer Tools - Internet Options - Advanced tab - option Check certificates revocation. Checked - works. But also not an option, we need administrator rights and do not forget to do this for each new client. Client-dependent solution. In the furnace.
3. Install the certificate locally. Valid only for 10-15 days. Option disappears.
4. Use unsigned version of dll. For Microsoft.Practices.Unity just did not find one. We also use the components of Infragistics, they have already taken care of this for a long time and supply two versions of libraries. Bin and Bin-Signed
5. I downloaded the source code Unity recompiled the library without a signature naturally. Works. But our project still uses Unity-dependent projects. Microsoft.Practices.ServiceLocation.dll, Unity.AutoRegistration.dll. It is necessary to recompile them. So-so in general variantik.
6. I tried to remove the digital signature from the finished dll. This is possible. But it's a chore. Also so-so option, although it may work
7. And here it is, the decision! In NET 3.5, the generatePublisherEvidence element, which disables certificate verification. Believe works! It remains to add only in the config:

  1. < onfiguration >
  2. < runtime >
  3. < GeneralizePublisherEvidence enabled = "false" />
  4. </ runtime >
  5. </ config >
* This source code was highlighted with Source Code Highlighter .


Later I found two stories similar to mine:

First case
Second case

This is how it is not easy security.

Source: https://habr.com/ru/post/134660/


All Articles