NDepend

Improve your .NET code quality with NDepend

Top 10 Visual Studio Refactoring Tips

With the version 2019 Visual Studio is now mature when it comes to refactoring. This post proposes a tour of the top 10 most used refactoring actions in my opinion.

Short GIF is an excellent way to help get started with those Visual Studio tips. See others related posts based also on short GIFs here:

1) Renaming an Identifier

With Ctrl+R,R you can rename any code identifier: a variable, a field, a class… The renaming experience is pretty clean when only one source file is concerned since all references in file get updated live while typing the new name:

Renaming a variable in Visual Studio
Renaming a variable in Visual Studio

When renaming an identifier impacts several source files, like when renaming a class, several UI details improve the user experience:

  • In the top-right panel we see: Renaming X references in Y files
  • In the top-right panel we get the checkbox: Rename file, this is quite useful since often the file name and the class name are in-sync.
  • We get the possibility to preview all changes in all files in a Preview Change window.
Renaming a class in Visual Studio
Renaming a class in Visual Studio

2) Extract Method

The hotkey Ctrl+. triggers the Quick Actions and Refactorings menu. If you are not used yet to Ctrl+. I’d advise training especially this one because it is a powerful shortcut. You’ll see that most other refactoring presented here rely on the Ctrl+. hotkey.

If one or several instructions are actually selected in a method, the Extract method and Extract local function menus are proposed. A large tooltip is immediately shown to preview the changes. Then just click Enter and terminate the refactoring action by naming the NewMethod identifier.

Extract Method with Visual Studio
Extract Method with Visual Studio

3) Remove and Sort Usings

To make your code cleaner it is recommended to maintain for each source file the list of using ordered alphabetically with unnecessary usings removed. Both actions can be done automatically with Visual Studio top menu > Edit > Intellisense > Remove and Sort Usings. I wish a default shortcut was assigned to this common refactoring (of course you can still assign a shortcut to this action from Visual Studio top menu > Tools > Options > Keyboards.).

Remove and Sort Usings with Visual Studio
Remove and Sort Usings with Visual Studio

Actually it is possible to remove all unnecessary usings at once in a Visual Studio project or solution thanks to the bulb that appears in the code editor gutter when selecting an unnecessary using faded away.

Remove unnecessary usings with Visual Studio
Remove unnecessary usings with Visual Studio

4) Add Missing Usings when Pasting

When pasting some code it is quite irritating to get some errors because of some missing usings. Once the code has been pasted, you can click Ctrl+. to ask Visual Studio to add missing usings for you:

Add missing usings after pasting with Visual Studio
Add missing usings after pasting with Visual Studio

5) Generate Property from Constructor and Generate Constructor from Properties

Once again the magical Ctrl+. hotkey can be used when selecting a parameter into a constructor signature, to generate the corresponding property.

However I haven’t found a way to generate several properties in a row. I’d expect that selecting several parameters and then Ctrl+. would propose to generate several properties in a row but it is not the case, and there is no Create properties for all parameters menu.

Generate property from constructor with Visual Studio
Generate property from constructor with Visual Studio

The same way you can generate a constructor from the selected properties.

Generate constructor from selected properties with Visual Studio
Generate constructor from selected properties with Visual Studio

Both quick actions work with fields also.

6) foreach to LINQ

When the editor carret is over a foreach loop, the hotkey Ctrl+. proposes to convert the foreach loop to a LINQ query. This conversion is not always possible but it is smart enough. For example it can convert a if(condition){continue} within the loop into a where condition LINQ clause.

Notice that typically loops are faster than LINQ queries because the compiler can optimize loops while LINQ queries extensively rely on method calls. But in non-performance-critical code region LINQ queries is often a more readable, concise and maintainable way of writing code.

Converting a foreach loop into a LINQ query with Visual Studio
Converting a foreach loop into a LINQ query with Visual Studio

7) Extract Interface

When the editor carret is over a class name the hotkey Ctrl+. proposes a quick-actions list that includes: extract an interface from the class members. Ctrl+R,I can be used instead to directly show the Extract Interface dialog. The Extract Interface dialog proposes to define the interface name (per defaut set to “I{class name}”) and the member list to include in the interface.

Extracting an interface from a class with Visual Studio
Extracting an interface from a class with Visual Studio

8) Move Type to Namespace

When the editor carret is over a type name, the hotkey Ctrl+. proposes the quick-actions list that includes: move to namespace. The Move to namespace dialog is smart enough to propose intellisense and auto-completion based on existing namespaces. However the type’s source file is not moved automatically to the folder corresponding to the namespace chosen, this must be done manually in the Solution Explorer. I hope this move will be done automatically in the future.

Move class to namespace with Visual Studio
Move class to namespace with Visual Studio

9) Add Parameter to a Method

You can add a named parameter to a method call location. Then the hotkey Ctrl+. proposes the refactoring Add parameters to the method called. The method signature is then refactored with the extra parameter but other calls of the method are left untouched. It means that now these other calls provoke a syntax error and must be fixed with the extra parameter.

Add parameter to a method with Visual Studio
Add parameter to a method with Visual Studio

10) Convert to interpolated string and simplify interpolation

When the carret is over a call to string.Format() call the hotkey Ctrl+. proposes the refactoring Convert to interpolated string. String interpolation with the syntax $”{parameter}” has been introduced with C#6 in 2015. Then if possible some elements like call to PadLeft() are grayed in code. This is a sign that the string interpolation can be simplified once again with the hotkey  Ctrl+. over those grayed elements.

Convert to interpolated string with Visual Studio
Convert to interpolated string with Visual Studio

Conclusion

Over the years thanks to massive effort put in Roslyn, Visual Studio got better and better when it comes to refactoring actions proposed out-of-the-box. Many more refactoring than those 10 are proposed: read the list of refactoring and list of quick-actions.

When we talk about Visual Studio and refactoring the case of Resharper immediately comes in the discussion. For more than a decade Resharper has been the tool of choice to improve the productivity with many refactoring actions and more great features. My independent opinion in the VS vs. R# debate (in 2020) is that R# is still a bit more powerful despite VS being now quite mature. However it seems to me that the fact that VS is now quite mature with refactoring is not popular enough, hence I hope this post can help spread the word. And if you ask, yes I still code with R# in VS despite R# slowing down a bit the IDE, but I find myself using it less often. Within the next years we can expect both VS improvements in terms of refactoring and R# improvements especially in terms of performance.


Actually the word refactoring has really two meanings:

  • Short and quick productivity refactoring actions as presented here.
  • Large scale refactoring that are necessary when the architecture of a legacy doesn’t fit anymore the planned evolution and maintainability requirements.

Large scale refactoring must be discussed extensively. The number one prerequisite for a successful large scale refactoring is a solid understanding of the legacy code architecture. This is where the tool NDepend with its new dependency graph and dependency matrix can really help. Here are two short videos that explain how:

12 Visual Studio Debugging Productivity Tips

In this post we assume the the reader knows the basics of debugging with Visual Studio:

  • F5 to start running with the debugger
  • F9 set breakpoint on the current line
  • F10 run till next breakpoint
  • F5 to resume the execution from a stopped program debugged
  • F11 step into the function (if the instruction pointer points to a function)
  • F10 step over the function (if the instruction pointer points to a function)
  • Shift+F11 step out the executed function
  • Pause execution
  • Attach to Process
  • Quick watch an element in source code with mouse hover
  • Debug Windows : Locals, Watch, Immediate, Modules, Stack Trace, Exception

Many developers handle their debugging sessions with this powerful-enough knowledge kit. However the Visual Studio Debugging tools have much more to offer. Here is a list of Visual Studio Debugging productivity tips. Note that those tips and shortcuts have been validated with Visual studio 2019 16.6 EN-US edition with no extension installed.

1) Run to Cursor

With the shortcut Ctrl+F10 you can tell the debugger to run until the line pointed by the cursor.

Run to Cursor Ctrl+F10
Run to Cursor Ctrl+F10

2) Run through here with a mouse click

When hovering the source code while debugging a Run execution through here green glyph appears. This glyph can be clicked.

Run Execution Through Here Glyph
Run Execution Through Here with a Mouse Click

3) Set next statement to here

The Run execution through here green glyph can be transformed into Set next statement to here by holding the key Ctrl. It is different than Run execution through here because the statement in between are not executed. Hence in the small animation below we can see in the Watch window that the reference obj remains null: the MyClass constructor in between hasn’t been executed.

Set next statement to here
Set next statement to here

4) Data breakpoint: Break when value changes

If you set a breakpoint to a non-static property setter it will be hit when changing the property value for all objects. The same behavior can be obtained for a single object thanks to the Locals (or Watch) window right click : Break When Value Changes menu.

This facility is illustrated with the animation above. The hit occurs only when obj2.Prop is changed, not when obj1.Prop is changed.

Note that a data breakpoint is bound to a live object during a debugging session. Hence it gets lost once the debugged process stops, it cannot be reused during future debugging session.

Note that the menu Break When Value Changes is also available when right clicking a field in the Locals window but unfortunately the debugger doesn’t break on field change, I am not sure if it’s a bug or a feature not yet implemented?

Data breakpoint: break when value changes
Data breakpoint: break when value changes

5) Conditional breakpoint

A condition can be attached to a breakpoint to break only in a certain scenario. In the animation below we define the breakpoint with condition i > 6 within the loop. Then we click Continue and can see that once the breakpoint is stopped, the i value is actually 7.

Conditional Breakpoint
Conditional Breakpoint

6) Trace breakpoint

Halting the program execution is the most common action upon a breakpoint hit. However you can choose instead to print some traces in the Output window without (or with) halting. This possibility is illustrated by the animation below where we trace the value of i from 0 to 9 in the Output window. Notice that a trace breakpoint has the diamond shape in the code editor gutter.

Note that both a condition and a trace action can be specified on a breakpoint.

Trace Breakpoint
Trace Breakpoint

7) Track Objects that Are Out-Of-Scope

In the Watch window objects are tracked by the name of their references in the currently executed scope. However when such tracked reference goes out-of-scope, it becomes meaningless in the context of the Watch window and it gets disabled, even though the referenced object is still live.

There are many situations where we’d like to continue tracking the state of an out-of-scope object. To do so, right click such reference in the Watch window, click the menu Make Object ID and add $1 in the items to watch (or $2 or $3… depending on how many object IDs you’ve already created).

The animation belows shows how to track the state of an out-of-scope object’s property getter that returns the actual date-time as a string. It shows well that when the reference obj goes out-of-scope in the context of Fct(), obj item to watch gets disabled and $1.Prop still gets updated.

Tracking an object whose reference goes out-of-scope
Tracking an object whose reference goes out-of-scope

8) View values returned by functions

The value returned by a function is sometime ignored by the source code. Or sometime this value is just not obviously accessible at debug-time.

Such returned value can be shown in the Debug > Windows > Autos windows. The pseudovariables $ReturnValue can also be used in the Immediate and Watch Windows to view the last function call returned value.

Note that the menu Debug > Windows > Autos is available only when the Visual Studio debugger is attached to a process and the program is halted by the debugger.

View the value returned by a function
View the value returned by a function

9) Reattach To Process

Since Visual Studio 2017 the Reattach to process Shift+Alt+P facility is proposed and it’s very handy. Once you’ve been attaching the debugger to a process Visual Studio remembers it and proposes to re-attach the debugger to the same process. Same is in italic because there is an heuristic here about the process identity:

  • If the process you’ve been attached to is still alive Reattach to process re-attach to it.
  • Else Visual Studio attempts to find a single process with the same previous process name and re-attach the debugger to it.
  • If several processes are found with this name, the Attach to Process dialog is opened with only those processes with same name shown
  • If no process with this name can be found the Attach to Process dialog is shown
Reattach To Process
Reattach To Process

Reattach To Process also works with debug session involving multiple processes. In this situation Visual Studio attempts to find all processes it has been attached to with the same heuristics explained above.

10) No-Side-Effect evaluation in Immediate Window and in the Watch Window

Sometime when evaluating an expression in the Immediate or in the Watch window some state gets changed. This behavior is often indesirable, you don’t want to corrupt the state of your debugged program just because you needed to evaluate the value of an expression. This situation is known as an Heisenbug , the term is a pun on the name of Werner Heisenberg, the physicist who first asserted the observer effect of quantum mechanics, which states that the act of observing a system inevitably alters its state.

To avoid changing any state you can suffix your expression with , nse (No-Side-Effect). This possibility is illustrated by the animation below (watch the _State value changing or not in the Watch window):

No Side Effect expression evaluation
No Side Effect expression evaluation

Here is ,nse used in the Watch window. This sample is less trivial than the previous one because of the Refresh evaluation button in the SideEffectFct() watched item.

No Side Effect expression evaluation in the Watch Window
No Side Effect expression evaluation in the Watch Window

11) Show Threads in Source

Debugging a multithreaded application is notoriously complex. Hopefully the Show Threads in Source button can help a lot.  It introduces marker icons in the editor gutter to keep track of the locations on which other threads are halted. This marker can be used to show the thread ids and eventually switch to another thread. Notice that a different marker glyph is shown if at least two threads are halted on the same location.

Show Threads In Source
Show Threads In Source

More tips to debug multithreaded applications are available in this Microsoft documentation: Get started debugging multithreaded applications (C#, Visual Basic, C++)

Here is the source code of this small demo if you’d like to play with it:

12) Debug source code decompiled from IL code

Often we depend on some black-box components: assemblies for which we don’t have the source code.

However when debugging a complex behavior it is convenient to observe and even debug the logic nested in black-boxes referenced. This is why since version 16.5 Visual Studio 2019 can generate some source code from compiled assemblies. Such source code is then debuggable. This feature is based on the OSS project ILSpy.

The decompilation menu can be proposed in the assembly right-click menu in the Modules window (as shown in the animation below) and in the Source Not Found or No Symbols Loaded dialogs.

Decompiling IL code to source code cannot be perfect because some source information is lost at compilation time. Hence this feature has a few limitations explained at the end of this official documentation: Generate source code from .NET assemblies while debugging.

Decompile IL code to source code that can be debugged
Decompile IL code to source code that can be debugged

Conclusion

Visual Studio shines but it especially shines when it comes to debugging. Here I tried to select some tips that are both quite hidden but often useful, I hope they will help improve your productivity.

 

 

Case Study: 2 Simple Principles to achieve High Code Maintainability

High Code Maintainability is the key to make both the management and the developers happy:

  • Maintainability lets a product evolves naturally at a sustained pace with controlled cost.
  • Maintainability lets developers add new features and improve existing ones without spending most of their time refactoring old dusty code and fixing bugs.

After 16 years of development on our product NDepend (first release in April 2004!) we came to the conclusion that:

Highly Maintainable Code can be achieved through two simple, objective and verifiable principles: Layered Architecture and High Test Coverage Ratio

Layered Architecture prevents entangled code, the well know spaghetti code phenomenon. Dependencies get mastered and when it is time for the code to evolve new classes and interfaces naturally integrate with existing ones.

High Test Coverage Ratio means that when code covered by tests get refactored, existing tests get impacted. With not much efforts the developer discovers regression problems and fix them before they go to production and become bugs to fix. The more code is covered by tests the more you’ll benefit from this shield.

When writing a tool for developers, the most satisfying part is to challenge the tool on its own code: this practice is named dogfooding. We just rewrote completely the dependency graph of NDepend so let’s use this important refactoring as a case study. Then we’ll see how to automatize the validation of these principles.

Case Study: Layered Architecture

Let’s first present the layered architecture principle and then the test coverage principle.

See below a graph of the 250+ classes, interfaces and enumerations used to implement the new dependency graph. A 2.500+ classes, methods and fields SVG vector dependency graph is available here.

The class GraphController is selected:

  • The blue classes are the ones directly used by GraphController
  • The light-blue classes are the ones indirectly used by GraphController (indirectly means used by a classes used by a class … used by GraphController). Clearly GraphController relies on everything.
  • The red classes are the ones mutually dependent with GraphController.
The NDepend Dependency Graph used to visualize its own code

Several things can be said on how this code is structured:

  • This is not an API so we can use namespaces the way we want. Here namespaces implement the concept of components.
  • Box size is proportional to the number of lines of code. We can see that the overall namespaces box size is well balanced. This is a good practice to avoid having a few monster components and tons of smaller components.
  • The biggest component in terms of number of classes and lines of code is the implementation of the Undo/Redo system. More than 30 actions are implemented (expand/collapse, change GroupBy, select/unselect, generate a call graph…). These actions are relatively low level in the structure. While they act on the entire system they are not coupled with the controller, the UI rendering or the layout computation.
  • The two lowest components are Base and Model. Both contain few logic and are used by almost all other components.

In the future, whether we add new actions on the graph or decide to improve the layout somehow, this architecture won’t undergo drastic modifications. Thanks to this view it’ll be easy to decide in which component to add our new classes or if new components should be added and what they can and cannot use.

Ideally the GraphControl class shouldn’t be entangled with the GraphController class. These two classes have been developed together. See below the coupling graph between GraphController and GraphControl. It has been obtained by double-clicking the red arrow between the two classes. It wouldn’t be difficult to introduce an interface to inject one implementation in the other one but we didn’t do it (see below the coupling graph between the two classes) . This is the key when it comes to care for maintainability: which move will offer the highest ROI? Not everything has to be perfect just for the sake of it. Experience shows that having only two classes entangled does not impact much the maintainability. We estimated that spending our resources to satisfy the two principles has a better ROI in the long run.

Coupling Graph between GraphController class and GraphControl class

 

Case Study: High Test Coverage Ratio

The graph implementation is 90% covered by tests. It is not because there is a lot of UI code that it should not been well tested. We didn’t spend a good part of our resources in writing tests just for the sake of it. We did it because we know by experience that it’ll pay off: probably a few bugs will be reported as for every 1.0 implementation although beta test phases already caught some. But we are confident that it won’t take a lot of resources to fix them. We can look forward the future confidently (like supporting properly .NET 5 that will be released in November 2020).

The picture below shows all namespace, classes and methods. Smaller rectangles are methods and the color of each rectangle indicates how well a method is covered by tests. Clearly we tolerate some gaps in UI code, while non UI code like Undo/Redo actions implementations are 100% covered. Here also experience tells us how to balance our resources and that everything does not have to be perfect to achieve high maintainability.

NDepend Graph Implementation 90% covered by tests

In terms of lines of code the NDepend Graph is not even 5% of the entire product, it is a tool in the toolset. The worst case scenario would be that each tool implementation regularly spits some bugs: all our resources would be spent fixing them, we couldn’t continue adding value to the product and the business would probably die at a point. Not even mentioning the frustration of users of a buggy product.

Each year we fix a few dozens of bugs that each impact few users but that doesn’t take us more than a tiny percentage of our overall development resources. The overall code base is 86.5% covered by tests and is entirely layered: maintenance doesn’t cost us much.

Typically at this point comes the remark: but code coverage is not enough, results must be asserted by unit-tests. And indeed, if nothing gets asserted nothing gets tested even if the code is entirely covered by tests.  We want tests to fail when something is going wrong. In this next post Case Study : Complex UI Testing I explain how millions of assertions get checked while running our test suite against the graph implementation.

Automatically Validate Layered Architecture and High Test Coverage Ratio

NDepend offers hundreds of default code rules but only 4 of them are used to validate these key points:

The fourth rule Avoid namespaces mutually dependent helps a lot to layer a large super-component. In this situation the first thing to do is to make sure there is no pair of components that use each other. For each such pair of namespaces matched, this rule has an heuristic and tells which type should not use which other type, same for method level. A technical-debt estimation is also given in terms of development effort it’ll cost to fix each pair. Here it says that 11 man-day (8 hours a day) should be spent if someone decides to layer the NHibernate code base. Unfortunately this is not possible because it would break thousands of client code base bound with it. Also let’s note that an interest estimation is also given in terms of: how much development effort does it takes per year if I let issues unfixed. Here this rule estimates that not fixing all those pairs of namespaces entangled costs 5 man-days a year to the development team.

Avoid Namespaces Mutually Dependent with advices on what to do and costs estimation

These rules can be validated during the build process (Azure DevOps / TFS, Jenkins, TeamCity, Bamboo, SonarQube…) and the team can know when the new code written diverges from these two maintainability goals.

 

Conclusion: Objective, Verifiable, Simple

What is interesting with these two simple concepts, layering and code coverage, is that they can be objectively applied, validated and measured. Last year in 2019 I wrote a blog post series on SOLID principles and there have been so much debate about how to apply them in the real-world. SOLID principles are a great way to improve our understanding of Object Oriented Programming and how encapsulation, abstraction, polymorphism, inheritance … should be used and not used. But when it comes to write maintainable code everyone has a different opinion.

If it is decided that the code structure should be layered there is not much debate about which part should be abstracted from other ones. If a class A should use a class B and B is in a higher layer than A, somehow an interface IB must be created at A level to inject the B implementation in A without breaking the layering.

These 2 concepts emerged over the years because we had the utter need to produce maintainable code. What I really like is that they are simple. And KISS (Keep It Simple Stupid) is a great principle in software engineering.

If a third principle should be added it would definitely be about user documentation: we offer free email support to users but we also offer tons of embedded and online documentation. Everytime a question starts to be asked a few times, we make sure that users can get the response immediately from both a tooltip (or a smart UI change) and from the online documentation. Some other ISV decides to make money with support. Personally I don’t find this fair because it is a clear incentive to produce rotted documentation and hence frictions for the user.

How did we obtain the image in this post

Let’s show that all those images in this post have been obtained within a few clicks.

  • First let’s search for Graph Panel in the entire NDepend code base (they get zoomed automatically).
  • Then let’s reset the metric view with NDepend.UI.Graph.* namespaces to get the colored treemap.
  • Then let’s go back to the graph and only keep NDepend.UI.Graph.* namespaces matched by the search.
  • Then un-group by parent assembly to get a graph made of namespaces only.
  • Then change the layout direction from Top to Bottom to have a nicer layout.
  • Then expand all namespaces to get all classes.
  • Finally expand all classes to get all methods and fields.
Using the NDepend Graph to obtain a clear view of the implementation of the Graph

 

Not planning now to migrate your .NET 4.8 legacy, is certainly a mistake

2020 will see the achievement of the massive remodeling of the .NET platform initiated by Microsoft in November 2014 with the introduction of .NET Core 1, with the promise of an open-source, a multi-platform and a modernizable framework (thanks to no rock-solid backward compatibility constraint) – everything that the .NET Framework isn’t. This U-turn in the Microsoft plans for .NET is part of the new Microsoft’s strategy initiated by Satya Nadella that became CEO of Microsoft in February 2014, succeeding to Steve Ballmer.

.NET 5 will be released in November this year. Within 6 years Microsoft will have succeeded a complete platform shift like no other. The .NET Core brand was here to make clear that two .NET platforms were living side by side. But now we know that the .NET Framework 4.8 won’t evolve anymore and that all Microsoft efforts will be put on .NET Core continuation with well scheduled releases ahead. Let’s use the term .NET OSS to designate [.NET Core, .NET 5, .NET 6…. [ in the remainder of this post.

We can expect an early beta of .NET 5 before July 2020. Today in January 2020 the .NET 5.0 milestone is 72% achieved.

By now, the way to get prepared to .NET 5 and later is to migrate to .NET Core 3.1. Despite the branding change from .NET Core 3.1 to .NET 5 it is no mystery that .NET 5 will be mostly based on the actual .NET Core platform.

The cost of migration from .NET 4.8 to .NET OSS can get pretty high, especially if the legacy relies on some deprecated APIS (like WCF, WWF, WebForms or AppDomain). Thus it may seems attractive to stick with .NET 4.8 if your application is intended to run on Windows only.

Why it is not a good idea to not anticipate the migration now?

.NET 4.8 won’t evolve but some security patches will be provided for as long as we can foresee. However we can predict that .NET 4.8 will be quickly considered as a thing-of-the-past:

  • Developer mindset: .NET OSS and also C# will evolve. There will come a point where it’ll feel pretty awkward for .NET programmers working with 4.8 to not be able to use all the new goodies. Could you imagine programming with C#3 nowadays?
  • Third-Party Libraries: The .NET 4.8 / .NET OSS increasing gap will push open-sourced libraries authors toward .NET OSS. The cost of maintaining two code bases will be too high for an OSS developer. If your .NET 4.8 application consumes some OSS libraries, not migrating it will put you in an awkward situation where you’ll have to maintain the OSS code consumed yourself! Certainly serious commercial libraries will be maintained on both platforms for a longer period of time, but not forever.
  • Performance: We can expect more and more performance improvements with .NET OSS.
  • Tooling: Tools will continue to evolve and with time, less and less tool will support .NET 4.8 application.

Recently I’ve discussed with Jean-Baptiste Evain that develops the OSS library Cecil. Jb is also responsible for UnityVS at MS. Here at NDepend we’re relying on Cecil for more than a decade. Cecil processes compiled .NET assemblies bytes and thus will obviously benefit from Span<T> only available on .NET Core. This concrete situation illustrates well the points mentioned above:

  • By using Span<T> Jb is not enthusiast to have to maintain two versions of Cecil, one relying on Span<T> and the .NET 4.8 one.
  • Even though these two versions will co-exist because it is too early to discard the .NET 4.8 version of Cecil used by many serious projects, it is a matter of a few years until .NET 4.8 Cecil version gets deprecated.
  • Without Span<T> the .NET 4.8 version of Cecil will be slower.

Our case

NDepend is still running on .NET 4.8. NDepend is a CI tool, a standalone UI tool, an Azure DevOps extension and a Visual Studio extension. Developing an extension is a sensitive situation because we need to align our platform with the platform of the host. VS is such a massive application that I don’t expect it to run on .NET 5 in 2021. On the other hand VS is evolving so quickly nowadays that this possibility is not totally excluded. It is also possible that Microsoft takes an incremental approach and that the main VS process (devenv.exe) will remain on .NET Fx 4.8 for a while, while children processes run on .NET OSS (VS runs with quite a few children processes!).

At this point the reasonable move for us is to anticipate the migration to .NET OSS mostly by compiling as much code as possible against .NET Standard 2.0, supported by both .NET Fx 4.7.2+ and .NET Core. We also need to make sure that our WPF and Winforms code will be easily movable (which shouldn’t be a problem since most of the WPF/Winforms APIs are supported by .NET 3.1). We are also mulling over on having our own child process(es) but all the UI part must remain in the main VS process.

We also keep in mind that it will be tricky to support the future VS version running on .NET OSS and previous VS versions running on .NET v4.8 for a few years.

Conclusion

Those like us still working on a large .NET 4.8 legacy are entering into a turbulence zone for the years to come. However for all the reasons explained above, we can expect that in not so long (2023? 2025?) successful applications still running on .NET 4.8 will be the exception. Certainly not anticipating legacy migration now is likely a strategic mistake.

SOLID Design: The Interface Segregation Principle (ISP)

After having covered The Open-Close Principle (OCP), The Liskov Substitution Principle (LSP) and the Single Responsibility Principle (SRP) let’s talk about the Interface Segregation Principle (ISP) which is the I in the SOLID acronym. The ISP definition is:

Client should not be forced to depend on methods it does not use.

It is all about interface, the common abstractions available in most OOP language such as C#, VB.NET or Java. A more complete and actionable explanation of ISP is:

ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces.

Roles and Responsibilities

When a class implements several shrunken role interfaces, it has several roles which might lead to think that such class has several responsibilities: it would then violate the Single Responsibility Services.

But a role is a finer-grained concept than a responsibility. An example of a role is the IDisposable interface:

This interface has a single method but it is implemented by a wide variety of classes: DB or network connections that need to be closed gracefully, UI elements that need to deallocate some bitmaps in memory… The only thing the IDisposable interface says to clients is that instances of IDisposable class needs a graceful shutdown.

Hence IDisposable represents a technical detail that the client needs to be aware of. It is much finer-grained concept than a responsibility.

A small interface is not necessarily a good abstraction

A single method interface often makes sense, an IExecutor that Execute(), an IVisitor that Visit(), an IParent that exposes Children { get; }. Often, such minimalist interface should be generic. For example the interface ICloneable available since the .NET Framework v1.1 is nowadays considered as a code smell: when using it the client needs to downcast the cloned Object reference returned to do anything useful with the cloned instance.

ICloneable has another major drawback: it doesn’t inform the client if the clone operation is deep or shallow. This problem is even more serious than the Object reference downcasting one: it is a real design problem. As we can see a minimalist interface is not necessarily a good abstraction. In this example, the lack of information means ambiguity for the client. This would have been better design:

A fat interface is not necessarily a design flaw

A rule like Avoid too large interfaces can certainly pinpoint most of the ISP violations. A threshold of 10 methods is proposed by default to define a too large interface.

However, as always with code metrics and static analysis, such rule can also spit some false positives. For example this fat interface is valid:

In such case the SuppressMessageAttribute can be used with a proper justification. Such justification embeds in the code itself the design decisions. It makes the source code more understandable and more maintainable:

ISP and the Liskov Substitution Principle (LSP)

ISP and LSP are like 2 faces of the same coin:

  • ISP is the client perspective: If an interface is too fat probably the client sees some behaviors it doesn’t care for.
  • LSP is the implementer perspective: If an interface is too fat probably a class that implements it won’t implement all its behaviors. Some behavior will end up throwing something like a NotSupportedException.

Remember the ICollection<T> interface already discussed in the LSP article. This interface forces all its implementers to implement an Add() method. From the Array class perspective, implementing ICollection<T> is a violation of the LSP because array doesn’t support element adding:

The same way many clients will only need a read-only view of consumed collections. ICollection<T> also violates the ISP: it forces those clients to be coupled with Add() / Insert() / Remove() methods they don’t need. The introduction of IReadOnlyCollection<T> solved both ISP and LSP violations.

This example also shows that ISP doesn’t necessarily mean that a class should implement several lightweight interfaces. It is fine to nest interfaces like russian-nesting-dolls. ICollection<T> is a bit fat, it does a lot, read, add, insert, remove, count… But this interface is well-adapted both for classes that are read/write collections and for clients that work on read/write collection. It makes more sense to nest both read/write behaviors into ICollection<T> than to decompose both behaviors into IReadOnlyCollection<T> and an hypothetical IWriteOnlyCollection<T> interface.

Btw, maybe you noticed that ICollection<T> actually doesn’t implement IReadOnlyCollection<T>. In an ideal world it should implement it but IReadOnlyCollection<T> was introduced several years after ICollection<T> and backward compatibility must be preserved: for example this class would have been broken if ICollection<T> was implementing IReadOnlyCollection<T>, because of the explicit interface implementation usage on ICollection<T>.Count:

Conclusion

ISP is about preventing inadvertent coupling between a client and some behaviors he/she won’t need. Being coupled with something unneeded is a problem:

  • In the best case it is a waste: this forces the client to consume precious brain-cycles to consider something he/she doesn’t need.
  • In the worst case it is error-prone: the client ends-up misusing the extra behaviors, like attempting to add an element to an array through ICollection<T>.Add().

As for all SOLID principles, ISP is better applied if you practice test-first, or at least, if you write tests and code at the same time. ISP is about the client perspective and writing tests transforms you for a while into a client of your code.

 


Out of curiosity I wrote this code query that can be re-used to attempt to measure compliance with the ISP.

This query estimates the ratio of usage of the methods of an interface over the maximum usage (maximum usage being when all types consuming an interface call all methods of the interface). Some work would be needed to transform this experimental query into a formal rule. For example the query needs to be smart about methods overloaded that can arguably be considered as a single method.

Nevertheless here are the raw results for non-public interfaces of the .NET framework implementation. Only non-public interfaces are considered because we need to also analyze some real clients of the interface:

927 types score tUsers interfaceMethods Full Name
IExceptionData 0.33 3 types 1 method Microsoft.Build.Tasks.Xsd.IExceptionData
IDtcNetworkAccessConfig 0.077 2 types 13 methods Microsoft.Tools.ServiceModel.WsatConfig .IDtcNetworkAccessConfig
INetFirewallOpenPort 0.6 1 type 15 methods Microsoft.Tools.ServiceModel.WsatConfig .INetFirewallOpenPort
INetFirewallOpenPortsCollection 0.6 1 type 5 methods Microsoft.Tools.ServiceModel.WsatConfig .INetFirewallOpenPortsCollection
INetFirewallProfile 0.071 1 type 14 methods Microsoft.Tools.ServiceModel.WsatConfig .INetFirewallProfile
INetFirewallPolicy 0.5 1 type 2 methods Microsoft.Tools.ServiceModel.WsatConfig .INetFirewallPolicy
INetFirewallMgr 0.2 1 type 5 methods Microsoft.Tools.ServiceModel.WsatConfig .INetFirewallMgr
IDtdInfo 0.056 23 types 7 methods System.Xml.IDtdInfo
IDtdAttributeListInfo 0.33 3 types 6 methods System.Xml.IDtdAttributeListInfo
IDtdAttributeInfo 0.39 4 types 7 methods System.Xml.IDtdAttributeInfo
IDtdDefaultAttributeInfo 0.11 9 types 4 methods System.Xml.IDtdDefaultAttributeInfo
IDtdEntityInfo 0.19 6 types 12 methods System.Xml.IDtdEntityInfo
IDtdParser 0.58 3 types 4 methods System.Xml.IDtdParser
IDtdParserAdapter 0.21 5 types 32 methods System.Xml.IDtdParserAdapter
IDtdParserAdapterWithValidation 0.75 2 types 2 methods System.Xml .IDtdParserAdapterWithValidation
IDtdParserAdapterV1 1 1 type 3 methods System.Xml.IDtdParserAdapterV1
IValidationEventHandling 0.3 10 types 2 methods System.Xml.IValidationEventHandling
IRemovableWriter 0.5 1 type 2 methods System.Xml.IRemovableWriter
INameScope 1 2 types 2 methods System.Xml.Serialization.INameScope
IXamlBuildProviderExtension 0.5 2 types 2 methods System.Xaml.Hosting .IXamlBuildProviderExtension
IXamlBuildProviderExtensionFactory 1 1 type 1 method System.Xaml.Hosting .IXamlBuildProviderExtensionFactory
IAddLineInfo 0.5 2 types 1 method MS.Internal.Xaml.Runtime.IAddLineInfo
ICheckIfInitialized 0.5 2 types 1 method MS.Internal.Xaml.Context .ICheckIfInitialized
IServiceDescriptionBuilder 1 1 type 1 method System.ServiceModel.Description .IServiceDescriptionBuilder
IExternalDataExchange 0.33 3 types 1 method System.ServiceModel.Activities .IExternalDataExchange
IWDEProgramNode 0 1 type 1 method System.Workflow.Runtime.DebugEngine .IWDEProgramNode
IWDEProgramPublisher 1 1 type 2 methods System.Workflow.Runtime.DebugEngine .IWDEProgramPublisher
ISupportWorkflowChanges 1 1 type 3 methods System.Workflow.ComponentModel .ISupportWorkflowChanges
ISupportAlternateFlow 1 11 types 1 method System.Workflow.ComponentModel .ISupportAlternateFlow
IDependencyObjectAccessor 0.3 10 types 4 methods System.Workflow.ComponentModel .IDependencyObjectAccessor
IWorkflowCoreRuntime 0.1 20 types 31 methods System.Workflow.ComponentModel .IWorkflowCoreRuntime
ITimerService 0.5 2 types 2 methods System.Workflow.ComponentModel .ITimerService
IWorkflowDesignerMessageSink 0.23 4 types 32 methods System.Workflow.ComponentModel.Design .IWorkflowDesignerMessageSink
IPropertyValueProvider 1 2 types 1 method System.Workflow.ComponentModel.Design .IPropertyValueProvider
IOleServiceProvider 0.5 2 types 1 method System.Workflow.ComponentModel.Compiler .IOleServiceProvider
IWorkflowBuildHostProperties 0.5 1 type 2 methods System.Workflow.ComponentModel.Compiler .IWorkflowBuildHostProperties
IWorkflowCompilerError 0 1 type 6 methods System.Workflow.ComponentModel.Compiler .IWorkflowCompilerError
IWorkflowCompilerErrorLogger 1 1 type 2 methods System.Workflow.ComponentModel.Compiler .IWorkflowCompilerErrorLogger
ISymUnmanagedReader 0.12 1 type 17 methods System.Workflow.ComponentModel.Compiler .ISymUnmanagedReader
ISymUnmanagedMethod 0.2 1 type 10 methods System.Workflow.ComponentModel.Compiler .ISymUnmanagedMethod
ISymUnmanagedDocument 0.1 1 type 10 methods System.Workflow.ComponentModel.Compiler .ISymUnmanagedDocument
IMetaDataDispenser 0.33 1 type 3 methods System.Workflow.ComponentModel.Compiler .IMetaDataDispenser
ITypeAuthorizer 0.33 3 types 1 method System.Workflow.ComponentModel .Serialization.ITypeAuthorizer
IDirectoryOperation 0.5 2 types 1 method System.Workflow.Activities .IDirectoryOperation
ICorrelationProvider 0.33 3 types 2 methods System.Workflow.Activities .ICorrelationProvider
IMethodResponseMessage 0.25 2 types 4 methods System.Workflow.Activities .IMethodResponseMessage
IDeliverMessage 0.33 3 types 2 methods System.Workflow.Activities .IDeliverMessage
IPropertyValueProvider 1 2 types 1 method System.Workflow.Activities.Common .IPropertyValueProvider
IAliasResolver 1 1 type 2 methods System.Resources.IAliasResolver
ISection 0 4 types 4 methods System.Deployment.Internal.Isolation .ISection
ISectionEntry 0 1 type 2 methods System.Deployment.Internal.Isolation .ISectionEntry
IEnumSTORE_ASSEMBLY_INSTALLATION_REFEREN CE 0 1 type 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_INSTALLATION_REFERE NCE
IEnumSTORE_DEPLOYMENT_METADATA 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA
IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY
IEnumSTORE_ASSEMBLY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY
IEnumSTORE_ASSEMBLY_FILE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_FILE
IEnumSTORE_CATEGORY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY
IEnumSTORE_CATEGORY_SUBCATEGORY 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_SUBCATEGORY
IEnumSTORE_CATEGORY_INSTANCE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_INSTANCE
IReferenceIdentity 0.071 7 types 4 methods System.Deployment.Internal.Isolation .IReferenceIdentity
IDefinitionIdentity 0.038 13 types 4 methods System.Deployment.Internal.Isolation .IDefinitionIdentity
IEnumDefinitionIdentity 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumDefinitionIdentity
IEnumReferenceIdentity 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumReferenceIdentity
IDefinitionAppId 0.059 17 types 6 methods System.Deployment.Internal.Isolation .IDefinitionAppId
IReferenceAppId 0.2 5 types 5 methods System.Deployment.Internal.Isolation .IReferenceAppId
IIdentityAuthority 0 1 type 18 methods System.Deployment.Internal.Isolation .IIdentityAuthority
IAppIdAuthority 0.062 3 types 16 methods System.Deployment.Internal.Isolation .IAppIdAuthority
IStore 0.24 4 types 20 methods System.Deployment.Internal.Isolation .IStore
IManifestParseErrorCallback 0 1 type 1 method System.Deployment.Internal.Isolation .IManifestParseErrorCallback
IManifestInformation 0.5 2 types 1 method System.Deployment.Internal.Isolation .IManifestInformation
IActContext 0.28 2 types 18 methods System.Deployment.Internal.Isolation .IActContext
ICMS 0.011 4 types 22 methods System.Deployment.Internal.Isolation .Manifest.ICMS
IDescriptionMetadataEntry 0.43 1 type 7 methods System.Deployment.Internal.Isolation .Manifest.IDescriptionMetadataEntry
IDeploymentMetadataEntry 0.17 1 type 6 methods System.Deployment.Internal.Isolation .Manifest.IDeploymentMetadataEntry
IMetadataSectionEntry 0.14 1 type 21 methods System.Deployment.Internal.Isolation .Manifest.IMetadataSectionEntry
FileDialogNative+IModalWindow 0 1 type 1 method System.Windows.Forms .FileDialogNative+IModalWindow
FileDialogNative+IShellItemArray 0.14 2 types 7 methods System.Windows.Forms .FileDialogNative+IShellItemArray
FileDialogNative+IFileDialog 0.017 5 types 24 methods System.Windows.Forms .FileDialogNative+IFileDialog
FileDialogNative+IFileOpenDialog 0.038 2 types 26 methods System.Windows.Forms .FileDialogNative+IFileOpenDialog
FileDialogNative+IFileSaveDialog 0 2 types 29 methods System.Windows.Forms .FileDialogNative+IFileSaveDialog
FileDialogNative+IFileDialogEvents 0 1 type 7 methods System.Windows.Forms .FileDialogNative+IFileDialogEvents
FileDialogNative+IShellItem 0 7 types 5 methods System.Windows.Forms .FileDialogNative+IShellItem
IKeyboardToolTip 0.23 4 types 13 methods System.Windows.Forms.IKeyboardToolTip
ISupportOleDropSource 1 1 type 2 methods System.Windows.Forms .ISupportOleDropSource
ISupportToolStripPanel 0.27 6 types 8 methods System.Windows.Forms .ISupportToolStripPanel
ListView+ListViewItemCollection+IInnerLi st 0.31 3 types 15 methods System.Windows.Forms .ListView+ListViewItemCollection+IInnerL ist
NativeMethods+IHTMLDocument 0 1 type 1 method System.Windows.Forms .NativeMethods+IHTMLDocument
UnsafeNativeMethods+IHTMLDocument 0 6 types 1 method System.Windows.Forms .UnsafeNativeMethods+IHTMLDocument
UnsafeNativeMethods+IHTMLDocument2 0.057 6 types 109 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLDocument2
UnsafeNativeMethods+IHTMLDocument3 0.049 3 types 41 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLDocument3
UnsafeNativeMethods+IHTMLDocument4 0.071 2 types 14 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLDocument4
UnsafeNativeMethods+IHTMLFramesCollectio n2 0.33 3 types 2 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLFramesCollecti on2
UnsafeNativeMethods+IHTMLLocation 0.039 4 types 19 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLLocation
UnsafeNativeMethods+IOmHistory 0.17 3 types 4 methods System.Windows.Forms .UnsafeNativeMethods+IOmHistory
UnsafeNativeMethods+IOmNavigator 0 1 type 19 methods System.Windows.Forms .UnsafeNativeMethods+IOmNavigator
UnsafeNativeMethods+IHTMLEventObj 0.14 5 types 25 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLEventObj
UnsafeNativeMethods+IHTMLEventObj2 0 1 type 56 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLEventObj2
UnsafeNativeMethods+IHTMLEventObj4 0 1 type 1 method System.Windows.Forms .UnsafeNativeMethods+IHTMLEventObj4
UnsafeNativeMethods+IHTMLElementCollecti on 0.083 4 types 6 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLElementCollect ion
UnsafeNativeMethods+IHTMLElement 0.043 7 types 87 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLElement
UnsafeNativeMethods+IHTMLElement2 0.065 3 types 98 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLElement2
UnsafeNativeMethods+IHTMLElement3 0.035 2 types 43 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLElement3
UnsafeNativeMethods+IHTMLStyle 0.0056 2 types 178 methods System.Windows.Forms .UnsafeNativeMethods+IHTMLStyle
UnsafeNativeMethods+ICorRuntimeHost 0.026 2 types 19 methods System.Windows.Forms .UnsafeNativeMethods+ICorRuntimeHost
UnsafeNativeMethods+IServiceProvider 0 1 type 1 method System.Windows.Forms .UnsafeNativeMethods+IServiceProvider
UnsafeNativeMethods+IAccessibleEx 0 1 type 4 methods System.Windows.Forms .UnsafeNativeMethods+IAccessibleEx
PropertyGridView+IMouseHookClient 0.5 2 types 1 method System.Windows.Forms .PropertyGridInternal .PropertyGridView+IMouseHookClient
IArrangedElement 0.12 32 types 9 methods System.Windows.Forms.Layout .IArrangedElement
IDataPointCustomPropertiesProvider 1 1 type 1 method System.Windows.Forms.DataVisualization .Charting .IDataPointCustomPropertiesProvider
IChartElement 0.25 4 types 4 methods System.Windows.Forms.DataVisualization .Charting.IChartElement
INameController 0.57 1 type 7 methods System.Windows.Forms.DataVisualization .Charting.INameController
IChartRenderingEngine 0.93 1 type 45 methods System.Windows.Forms.DataVisualization .Charting.IChartRenderingEngine
IDesignerMessageBoxDialog 0.5 2 types 1 method System.Windows.Forms.DataVisualization .Charting.IDesignerMessageBoxDialog
IFormula 0.25 2 types 2 methods System.Windows.Forms.DataVisualization .Charting.Formulas.IFormula
IChartType 0.11 13 types 22 methods System.Windows.Forms.DataVisualization .Charting.ChartTypes.IChartType
ICircularChartType 0.17 5 types 6 methods System.Windows.Forms.DataVisualization .Charting.ChartTypes.ICircularChartType
IBorderType 0.3 4 types 5 methods System.Windows.Forms.DataVisualization .Charting.Borders3D.IBorderType
INotifyConnection2 0.5 2 types 2 methods System.Web.Services.Interop .INotifyConnection2
INotifySink2 0.5 2 types 4 methods System.Web.Services.Interop.INotifySink2
INotifySource2 0 1 type 1 method System.Web.Services.Interop .INotifySource2
IDeviceSpecificChoiceDesigner 0.5 4 types 2 methods System.Web.UI.Design.MobileControls .IDeviceSpecificChoiceDesigner
IDeviceSpecificDesigner 0.15 11 types 10 methods System.Web.UI.Design.MobileControls .IDeviceSpecificDesigner
IListDesigner 0.05 2 types 10 methods System.Web.UI.Design.MobileControls .IListDesigner
IRefreshableDeviceSpecificEditor 0.5 2 types 7 methods System.Web.UI.Design.MobileControls .IRefreshableDeviceSpecificEditor
NativeMethods+IStream 0 1 type 11 methods System.Web.UI.Design.MobileControls .NativeMethods+IStream
NativeMethods+IHTMLElement 0.0077 3 types 87 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLElement
NativeMethods+IHTMLDocument2 0.0055 5 types 109 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLDocument2
NativeMethods+IHTMLDocument3 0.012 2 types 41 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLDocument3
NativeMethods+IHTMLStyleSheet 0 1 type 21 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLStyleSheet
NativeMethods+IHTMLStyle 0 1 type 178 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLStyle
NativeMethods+IHTMLElementCollection 0 1 type 6 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLElementCollection
NativeMethods+IHTMLDOMNode 0 1 type 20 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLDOMNode
NativeMethods+IOleContainer 0 2 types 3 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleContainer
NativeMethods+IOleClientSite 0 1 type 6 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleClientSite
NativeMethods+IOleDocumentSite 0 1 type 1 method System.Web.UI.Design.MobileControls .NativeMethods+IOleDocumentSite
NativeMethods+IOleDocumentView 0.15 2 types 13 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleDocumentView
NativeMethods+IOleInPlaceSite 0 1 type 12 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleInPlaceSite
NativeMethods+IOleInPlaceFrame 0 1 type 12 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleInPlaceFrame
NativeMethods+IOleInPlaceUIWindow 0 2 types 6 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleInPlaceUIWindow
NativeMethods+IDocHostUIHandler 0 1 type 15 methods System.Web.UI.Design.MobileControls .NativeMethods+IDocHostUIHandler
NativeMethods+IOleInPlaceActiveObject 0 2 types 7 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleInPlaceActiveObject
NativeMethods+IOleObject 0.048 2 types 21 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleObject
NativeMethods+IOleCommandTarget 0 2 types 2 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleCommandTarget
NativeMethods+IOleDropTarget 0 2 types 4 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleDropTarget
NativeMethods+IOleDataObject 0 2 types 9 methods System.Web.UI.Design.MobileControls .NativeMethods+IOleDataObject
NativeMethods+IEnumOLEVERB 0 1 type 4 methods System.Web.UI.Design.MobileControls .NativeMethods+IEnumOLEVERB
NativeMethods+IAdviseSink 0 1 type 5 methods System.Web.UI.Design.MobileControls .NativeMethods+IAdviseSink
NativeMethods+IHTMLBodyElement 0.014 2 types 35 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLBodyElement
NativeMethods+IPersistStreamInit 0.083 2 types 6 methods System.Web.UI.Design.MobileControls .NativeMethods+IPersistStreamInit
NativeMethods+IHTMLElement2 0.0094 3 types 106 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLElement2
NativeMethods+IHTMLRectCollection 0.33 2 types 3 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLRectCollection
NativeMethods+IHTMLCurrentStyle 0 1 type 67 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLCurrentStyle
NativeMethods+IHTMLRect 0.12 2 types 8 methods System.Web.UI.Design.MobileControls .NativeMethods+IHTMLRect
IListControl 1 1 type 2 methods System.Web.UI.MobileControls .IListControl
IScriptResourceHandler 1 1 type 3 methods System.Web.Handlers .IScriptResourceHandler
IContractGeneratorReferenceTypeLoader 0.5 2 types 3 methods System.Web.Compilation.WCFModel .IContractGeneratorReferenceTypeLoader
IContractGeneratorReferenceTypeLoader2 1 1 type 1 method System.Web.Compilation.WCFModel .IContractGeneratorReferenceTypeLoader2
IClientScriptManager 0.14 5 types 7 methods System.Web.UI.IClientScriptManager
IClientUrlResolver 0.4 5 types 2 methods System.Web.UI.IClientUrlResolver
ICompilationSection 1 1 type 1 method System.Web.UI.ICompilationSection
IControl 0.25 2 types 2 methods System.Web.UI.IControl
ICustomErrorsSection 0.5 2 types 2 methods System.Web.UI.ICustomErrorsSection
IDeploymentSection 1 1 type 1 method System.Web.UI.IDeploymentSection
IHtmlForm 0.33 3 types 4 methods System.Web.UI.IHtmlForm
IPage 0.12 8 types 31 methods System.Web.UI.IPage
IScriptManagerInternal 0.17 4 types 12 methods System.Web.UI.IScriptManagerInternal
IDynamicQueryable 0.14 2 types 7 methods System.Web.UI.WebControls .IDynamicQueryable
ILinqToSql 0.67 1 type 6 methods System.Web.UI.WebControls.ILinqToSql
ILinqDataSourceChooseContextType 0.44 2 types 8 methods System.Web.UI.Design.WebControls .ILinqDataSourceChooseContextType
ILinqDataSourceChooseContextTypePanel 0.5 2 types 4 methods System.Web.UI.Design.WebControls .ILinqDataSourceChooseContextTypePanel
ILinqDataSourceConfiguration 0.5 2 types 8 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfiguration
ILinqDataSourceConfigurationPanel 0.5 2 types 8 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigurationPanel
ILinqDataSourceConfigureAdvanced 0.5 2 types 1 method System.Web.UI.Design.WebControls .ILinqDataSourceConfigureAdvanced
ILinqDataSourceConfigureAdvancedForm 0.33 3 types 4 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureAdvancedForm
ILinqDataSourceConfigureGroupBy 0.42 2 types 6 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureGroupBy
ILinqDataSourceConfigureGroupByPanel 0.33 3 types 7 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureGroupByPanel
ILinqDataSourceConfigureOrderBy 0.33 2 types 3 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureOrderBy
ILinqDataSourceConfigureOrderByForm 0.33 3 types 6 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureOrderByForm
ILinqDataSourceConfigureSelect 0.42 2 types 6 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureSelect
ILinqDataSourceConfigureSelectPanel 0.33 3 types 22 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureSelectPanel
ILinqDataSourceConfigureWhere 0.25 4 types 16 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureWhere
ILinqDataSourceConfigureWhereForm 0.28 4 types 15 methods System.Web.UI.Design.WebControls .ILinqDataSourceConfigureWhereForm
ILinqDataSourceContextTypeItem 0.22 9 types 3 methods System.Web.UI.Design.WebControls .ILinqDataSourceContextTypeItem
ILinqDataSourceDesignerHelper 0.086 13 types 67 methods System.Web.UI.Design.WebControls .ILinqDataSourceDesignerHelper
ILinqDataSourceProjection 0.25 5 types 8 methods System.Web.UI.Design.WebControls .ILinqDataSourceProjection
ILinqDataSourcePropertyItem 0.099 22 types 11 methods System.Web.UI.Design.WebControls .ILinqDataSourcePropertyItem
ILinqDataSourceStatementEditorForm 0.38 2 types 4 methods System.Web.UI.Design.WebControls .ILinqDataSourceStatementEditorForm
ILinqDataSourceWizardForm 0.33 6 types 2 methods System.Web.UI.Design.WebControls .ILinqDataSourceWizardForm
ILinqDataSourceWrapper 0.5 2 types 44 methods System.Web.UI.Design.WebControls .ILinqDataSourceWrapper
IMetaChildrenColumn 0.17 1 type 6 methods System.Web.DynamicData .IMetaChildrenColumn
IMetaColumn 0.073 6 types 39 methods System.Web.DynamicData.IMetaColumn
IMetaForeignKeyColumn 0.17 2 types 9 methods System.Web.DynamicData .IMetaForeignKeyColumn
IMetaModel 0.019 3 types 18 methods System.Web.DynamicData.IMetaModel
IMetaTable 0.035 10 types 43 methods System.Web.DynamicData.IMetaTable
MetaColumn+IMetaColumnMetadata 0.37 3 types 20 methods System.Web.DynamicData .MetaColumn+IMetaColumnMetadata
IClrStrongNameUsingIntPtr 0.24 1 type 25 methods Microsoft.Runtime.Hosting .IClrStrongNameUsingIntPtr
IClrStrongName 0.36 1 type 25 methods Microsoft.Runtime.Hosting.IClrStrongName
IRequestCompletedNotifier 0.5 2 types 1 method System.Web.IRequestCompletedNotifier
IBufferAllocator 0.083 3 types 4 methods System.Web.IBufferAllocator
IBufferAllocator<T> 0.33 4 types 3 methods System.Web.IBufferAllocator<T>
IAllocatorProvider 0.25 5 types 4 methods System.Web.IAllocatorProvider
HttpApplication+IExecutionStep 0.2 5 types 3 methods System.Web .HttpApplication+IExecutionStep
IHttpResponseElement 0.83 2 types 3 methods System.Web.IHttpResponseElement
IHttpHandlerFactory2 1 1 type 1 method System.Web.IHttpHandlerFactory2
IPartitionInfo 0.25 4 types 1 method System.Web.IPartitionInfo
IAsyncAbortableWebSocket 0.5 2 types 1 method System.Web.WebSockets .IAsyncAbortableWebSocket
IWebSocketPipe 0.5 2 types 4 methods System.Web.WebSockets.IWebSocketPipe
IUnmanagedWebSocketContext 0.5 2 types 5 methods System.Web.WebSockets .IUnmanagedWebSocketContext
IPerfCounters 0.12 4 types 4 methods System.Web.Util.IPerfCounters
ISyncContextLock 0.33 3 types 1 method System.Web.Util.ISyncContextLock
ISyncContext 0.2 5 types 2 methods System.Web.Util.ISyncContext
ITypedWebObjectFactory 1 4 types 1 method System.Web.Util.ITypedWebObjectFactory
ICustomRuntimeRegistrationToken 0 2 types 1 method System.Web.Hosting .ICustomRuntimeRegistrationToken
IProcessSuspendListener 1 1 type 1 method System.Web.Hosting .IProcessSuspendListener
IProcessResumeCallback 0.5 2 types 1 method System.Web.Hosting .IProcessResumeCallback
ICustomRuntime 0 3 types 3 methods System.Web.Hosting.ICustomRuntime
IStateFormatter2 0.62 8 types 2 methods System.Web.UI.IStateFormatter2
IPageAsyncTask 0.5 2 types 1 method System.Web.UI.IPageAsyncTask
IAssemblyDependencyParser 1 1 type 1 method System.Web.UI.IAssemblyDependencyParser
IScriptResourceMapping 0.5 3 types 2 methods System.Web.UI.IScriptResourceMapping
IScriptResourceDefinition 0.33 3 types 8 methods System.Web.UI.IScriptResourceDefinition
IScriptManager 0.15 11 types 17 methods System.Web.UI.IScriptManager
ITagNameToTypeMapper 1 1 type 1 method System.Web.UI.ITagNameToTypeMapper
IRenderOuterTableControl 1 1 type 3 methods System.Web.UI.IRenderOuterTableControl
IWizardSideBarListControl 0.1 5 types 12 methods System.Web.UI.WebControls .IWizardSideBarListControl
IWebPartMenuUser 1 1 type 16 methods System.Web.UI.WebControls.WebParts .IWebPartMenuUser
NativeComInterfaces+IAdsPathname 0.12 3 types 11 methods System.Web.Security .NativeComInterfaces+IAdsPathname
NativeComInterfaces+IAdsLargeInteger 0.5 3 types 4 methods System.Web.Security .NativeComInterfaces+IAdsLargeInteger
IDataProtectorFactory 0.5 2 types 1 method System.Web.Security.Cryptography .IDataProtectorFactory
ICryptoServiceProvider 1 1 type 1 method System.Web.Security.Cryptography .ICryptoServiceProvider
IMasterKeyProvider 0.5 2 types 2 methods System.Web.Security.Cryptography .IMasterKeyProvider
ICryptoAlgorithmFactory 0.5 2 types 2 methods System.Web.Security.Cryptography .ICryptoAlgorithmFactory
ICryptoService 0.83 6 types 2 methods System.Web.Security.Cryptography .ICryptoService
IAssemblyCache 0.2 2 types 5 methods System.Web.Configuration.IAssemblyCache
IConfigMapPath2 0.67 2 types 3 methods System.Web.Configuration.IConfigMapPath2
IServerConfig 0.2 6 types 5 methods System.Web.Configuration.IServerConfig
IServerConfig2 1 1 type 1 method System.Web.Configuration.IServerConfig2
IDataPointCustomPropertiesProvider 1 1 type 1 method System.Web.UI.DataVisualization.Charting .IDataPointCustomPropertiesProvider
IChartElement 0.25 3 types 4 methods System.Web.UI.DataVisualization.Charting .IChartElement
INameController 0.57 1 type 7 methods System.Web.UI.DataVisualization.Charting .INameController
IChartRenderingEngine 0.93 1 type 45 methods System.Web.UI.DataVisualization.Charting .IChartRenderingEngine
IDesignerMessageBoxDialog 0.5 2 types 1 method System.Web.UI.DataVisualization.Charting .IDesignerMessageBoxDialog
IFormula 0.25 2 types 2 methods System.Web.UI.DataVisualization.Charting .Formulas.IFormula
IChartType 0.11 14 types 22 methods System.Web.UI.DataVisualization.Charting .ChartTypes.IChartType
ICircularChartType 0.17 5 types 6 methods System.Web.UI.DataVisualization.Charting .ChartTypes.ICircularChartType
IBorderType 0.3 4 types 5 methods System.Web.UI.DataVisualization.Charting .Borders3D.IBorderType
IMembershipAdapter 0.27 3 types 5 methods System.Web.Security.IMembershipAdapter
ICustomLoaderHelperFunctions 0.5 2 types 4 methods System.Web.Hosting .ICustomLoaderHelperFunctions
IPromotedEnlistment 0.089 14 types 12 methods System.Transactions.IPromotedEnlistment
IEnlistmentNotificationInternal 0.28 8 types 4 methods System.Transactions .IEnlistmentNotificationInternal
ISinglePhaseNotificationInternal 0.25 4 types 1 method System.Transactions .ISinglePhaseNotificationInternal
IVoterBallotShim 0.5 2 types 1 method System.Transactions.Oletx .IVoterBallotShim
IPhase0EnlistmentShim 0.38 4 types 2 methods System.Transactions.Oletx .IPhase0EnlistmentShim
IEnlistmentShim 0.5 2 types 3 methods System.Transactions.Oletx .IEnlistmentShim
ITransactionShim 0.25 4 types 8 methods System.Transactions.Oletx .ITransactionShim
IResourceManagerShim 0.44 3 types 3 methods System.Transactions.Oletx .IResourceManagerShim
IDtcProxyShimFactory 0.2 5 types 8 methods System.Transactions.Oletx .IDtcProxyShimFactory
ITransactionNativeInternal 0.33 1 type 3 methods System.Transactions.Oletx .ITransactionNativeInternal
IWebFaultException 1 1 type 4 methods System.ServiceModel.Web .IWebFaultException
IDuplexRouterCallback 0.33 3 types 2 methods System.ServiceModel.Routing .IDuplexRouterCallback
IRoutingClient 0.23 5 types 7 methods System.ServiceModel.Routing .IRoutingClient
IAsyncEventArgs 0.7 5 types 2 methods System.Runtime.IAsyncEventArgs
IClassFactory 0.25 2 types 2 methods IClassFactory
IOperationContractAttributeProvider 1 1 type 1 method System.ServiceModel .IOperationContractAttributeProvider
ICatalog2 0.018 1 type 57 methods System.ServiceModel.ComIntegration .ICatalog2
ICatalogObject 0.24 3 types 7 methods System.ServiceModel.ComIntegration .ICatalogObject
ICatalogCollection 0.17 3 types 16 methods System.ServiceModel.ComIntegration .ICatalogCollection
ICreateServiceChannel 1 1 type 1 method System.ServiceModel.ComIntegration .ICreateServiceChannel
IMoniker 0 1 type 20 methods System.ServiceModel.ComIntegration .IMoniker
IParseDisplayName 0 1 type 1 method System.ServiceModel.ComIntegration .IParseDisplayName
IProvideChannelBuilderSettings 0.12 4 types 4 methods System.ServiceModel.ComIntegration .IProvideChannelBuilderSettings
IProxyCreator 0.5 2 types 4 methods System.ServiceModel.ComIntegration .IProxyCreator
IProxyManager 0 4 types 6 methods System.ServiceModel.ComIntegration .IProxyManager
IProxyProvider 0.5 2 types 2 methods System.ServiceModel.ComIntegration .IProxyProvider
IPseudoDispatch 0 1 type 2 methods System.ServiceModel.ComIntegration .IPseudoDispatch
ITransactionProxy 0 1 type 7 methods System.ServiceModel.ComIntegration .ITransactionProxy
ITransactionVoterBallotAsync2 0 1 type 1 method System.ServiceModel.ComIntegration .ITransactionVoterBallotAsync2
ITransactionVoterNotifyAsync2 0.4 2 types 5 methods System.ServiceModel.ComIntegration .ITransactionVoterNotifyAsync2
ITypeCacheManager 0.33 3 types 4 methods System.ServiceModel.ComIntegration .ITypeCacheManager
IPersistStream 0.2 3 types 5 methods System.ServiceModel.ComIntegration .IPersistStream
IServiceThreadPoolConfig 1 1 type 2 methods System.ServiceModel.ComIntegration .IServiceThreadPoolConfig
IServicePartitionConfig 1 1 type 2 methods System.ServiceModel.ComIntegration .IServicePartitionConfig
IServiceSysTxnConfig 0.14 1 type 7 methods System.ServiceModel.ComIntegration .IServiceSysTxnConfig
IServiceSxsConfig 1 1 type 3 methods System.ServiceModel.ComIntegration .IServiceSxsConfig
IServiceTransactionConfig 0.17 1 type 6 methods System.ServiceModel.ComIntegration .IServiceTransactionConfig
IServiceCall 0 1 type 1 method System.ServiceModel.ComIntegration .IServiceCall
IServiceActivity 0.25 2 types 4 methods System.ServiceModel.ComIntegration .IServiceActivity
IComThreadingInfo 0.17 3 types 4 methods System.ServiceModel.ComIntegration .IComThreadingInfo
IObjectContextInfo 0.3 2 types 5 methods System.ServiceModel.ComIntegration .IObjectContextInfo
IContractResolver 0.2 5 types 1 method System.ServiceModel.Description .IContractResolver
ServiceMetadataExtension+IHttpGetMetadat a 0 2 types 1 method System.ServiceModel.Description .ServiceMetadataExtension+IHttpGetMetada ta
IWrappedBodyTypeGenerator 0.25 4 types 3 methods System.ServiceModel.Description .IWrappedBodyTypeGenerator
WbemNative+IWbemProviderInit 0 1 type 1 method System.ServiceModel.Administration .WbemNative+IWbemProviderInit
WbemNative+IWbemDecoupledRegistrar 0.5 2 types 2 methods System.ServiceModel.Administration .WbemNative+IWbemDecoupledRegistrar
WbemNative+IWbemServices 0.022 4 types 23 methods System.ServiceModel.Administration .WbemNative+IWbemServices
WbemNative+IWbemClassObject 0.056 6 types 24 methods System.ServiceModel.Administration .WbemNative+IWbemClassObject
WbemNative+IWbemContext 0 5 types 9 methods System.ServiceModel.Administration .WbemNative+IWbemContext
WbemNative+IWbemProviderInitSink 0.5 2 types 1 method System.ServiceModel.Administration .WbemNative+IWbemProviderInitSink
WbemNative+IWbemObjectSink 0.33 6 types 2 methods System.ServiceModel.Administration .WbemNative+IWbemObjectSink
WbemNative+IEnumWbemClassObject 0 2 types 5 methods System.ServiceModel.Administration .WbemNative+IEnumWbemClassObject
WbemNative+IWbemQualifierSet 0 1 type 7 methods System.ServiceModel.Administration .WbemNative+IWbemQualifierSet
IWmiProvider 0.5 2 types 5 methods System.ServiceModel.Administration .IWmiProvider
IWmiInstances 0.75 8 types 2 methods System.ServiceModel.Administration .IWmiInstances
IWmiInstance 0.44 22 types 3 methods System.ServiceModel.Administration .IWmiInstance
IWmiMethodContext 0.27 3 types 5 methods System.ServiceModel.Administration .IWmiMethodContext
IWmiInstanceProvider 1 3 types 2 methods System.ServiceModel.Administration .IWmiInstanceProvider
IFunctionLibrary 1 1 type 1 method System.ServiceModel.Dispatcher .IFunctionLibrary
INodeCounter 0.5 2 types 6 methods System.ServiceModel.Dispatcher .INodeCounter
IItemComparer<K,V> 0.5 2 types 1 method System.ServiceModel.Dispatcher .IItemComparer<K,V>
ConcurrencyBehavior+IWaiter 0.5 2 types 1 method System.ServiceModel.Dispatcher .ConcurrencyBehavior+IWaiter
IClientFaultFormatter 0.33 6 types 1 method System.ServiceModel.Dispatcher .IClientFaultFormatter
IDispatchFaultFormatter 0.22 9 types 1 method System.ServiceModel.Dispatcher .IDispatchFaultFormatter
IDispatchFaultFormatterWrapper 0.5 1 type 2 methods System.ServiceModel.Dispatcher .IDispatchFaultFormatterWrapper
IChannelBinder 0.076 23 types 20 methods System.ServiceModel.Dispatcher .IChannelBinder
IListenerBinder 0.3 4 types 5 methods System.ServiceModel.Dispatcher .IListenerBinder
IManualConcurrencyOperationInvoker 0.56 3 types 3 methods System.ServiceModel.Dispatcher .IManualConcurrencyOperationInvoker
IInvokeReceivedNotification 0.19 8 types 2 methods System.ServiceModel.Dispatcher .IInvokeReceivedNotification
IResumeMessageRpc 0.17 8 types 6 methods System.ServiceModel.Dispatcher .IResumeMessageRpc
IInstanceTransaction 1 1 type 1 method System.ServiceModel.Dispatcher .IInstanceTransaction
IInstanceContextManager 0.4 1 type 10 methods System.ServiceModel.Dispatcher .IInstanceContextManager
ISessionThrottleNotification 1 1 type 1 method System.ServiceModel.Dispatcher .ISessionThrottleNotification
IConfigurationContextProviderInternal 0.33 3 types 2 methods System.ServiceModel.Configuration .IConfigurationContextProviderInternal
ILockingQueue 1 1 type 2 methods System.ServiceModel.Channels .ILockingQueue
IChannelDemuxer 1 2 types 7 methods System.ServiceModel.Channels .IChannelDemuxer
IChannelDemuxFailureHandler 0.16 11 types 4 methods System.ServiceModel.Channels .IChannelDemuxFailureHandler
IChannelAcceptor<TChannel> 0 12 types 6 methods System.ServiceModel.Channels .IChannelAcceptor<TChannel>
IRequestReplyCorrelator 0.17 6 types 2 methods System.ServiceModel.Channels .IRequestReplyCorrelator
ICorrelatorKey 0.5 2 types 2 methods System.ServiceModel.Channels .ICorrelatorKey
ICommunicationWaiter 0.75 2 types 2 methods System.ServiceModel.Channels .ICommunicationWaiter
RemoteEndpointMessageProperty+IRemoteEnd pointProvider 0.5 2 types 2 methods System.ServiceModel.Channels .RemoteEndpointMessageProperty+IRemoteEn dpointProvider
IRequestBase 0.33 1 type 3 methods System.ServiceModel.Channels .IRequestBase
IRequest 0 3 types 2 methods System.ServiceModel.Channels.IRequest
IAsyncRequest 0 3 types 2 methods System.ServiceModel.Channels .IAsyncRequest
IConnectionOrientedListenerSettings 0 5 types 4 methods System.ServiceModel.Channels .IConnectionOrientedListenerSettings
ITransportFactorySettings 0.2 16 types 5 methods System.ServiceModel.Channels .ITransportFactorySettings
IConnectionOrientedTransportFactorySetti ngs 0.092 19 types 4 methods System.ServiceModel.Channels .IConnectionOrientedTransportFactorySett ings
IConnectionOrientedTransportChannelFacto rySettings 0 6 types 2 methods System.ServiceModel.Channels .IConnectionOrientedTransportChannelFact orySettings
ITcpChannelFactorySettings 0.5 2 types 1 method System.ServiceModel.Channels .ITcpChannelFactorySettings
IHttpTransportFactorySettings 0.042 12 types 2 methods System.ServiceModel.Channels .IHttpTransportFactorySettings
IPipeTransportFactorySettings 0.33 3 types 1 method System.ServiceModel.Channels .IPipeTransportFactorySettings
ITransportManagerRegistration 0 7 types 3 methods System.ServiceModel.Channels .ITransportManagerRegistration
IChannelBindingProvider 0.5 11 types 2 methods System.ServiceModel.Channels .IChannelBindingProvider
IStreamUpgradeChannelBindingProvider 0.5 6 types 2 methods System.ServiceModel.Channels .IStreamUpgradeChannelBindingProvider
IConnection 0.078 62 types 19 methods System.ServiceModel.Channels.IConnection
IConnectionInitiator 0.095 7 types 3 methods System.ServiceModel.Channels .IConnectionInitiator
IConnectionListener 0.12 8 types 3 methods System.ServiceModel.Channels .IConnectionListener
IMessageSource 0.14 7 types 6 methods System.ServiceModel.Channels .IMessageSource
ISingletonChannelListener 0.14 7 types 2 methods System.ServiceModel.Channels .ISingletonChannelListener
ISocketListenerSettings 0.5 2 types 3 methods System.ServiceModel.Channels .ISocketListenerSettings
HttpChannelListener+IHttpAuthenticationC ontext 0.38 2 types 4 methods System.ServiceModel.Channels .HttpChannelListener+IHttpAuthentication Context
HttpRequestMessageProperty+IHttpHeaderPr ovider 0.25 4 types 1 method System.ServiceModel.Channels .HttpRequestMessageProperty+IHttpHeaderP rovider
IWebMessageEncoderHelper 1 1 type 1 method System.ServiceModel.Channels .IWebMessageEncoderHelper
ITransportPolicyImport 1 2 types 1 method System.ServiceModel.Channels .ITransportPolicyImport
IPoisonHandlingStrategy 0.5 2 types 3 methods System.ServiceModel.Channels .IPoisonHandlingStrategy
IMsmqMessagePool 0.25 4 types 2 methods System.ServiceModel.Channels .IMsmqMessagePool
IPostRollbackErrorStrategy 1 2 types 1 method System.ServiceModel.Channels .IPostRollbackErrorStrategy
MsmqUri+IAddressTranslator 0.29 26 types 3 methods System.ServiceModel.Channels .MsmqUri+IAddressTranslator
IReliableChannelBinder 0.07 47 types 36 methods System.ServiceModel.Channels .IReliableChannelBinder
IClientReliableChannelBinder 0.083 16 types 9 methods System.ServiceModel.Channels .IClientReliableChannelBinder
IServerReliableChannelBinder 0.12 24 types 5 methods System.ServiceModel.Channels .IServerReliableChannelBinder
IReliableFactorySettings 0.19 10 types 10 methods System.ServiceModel.Channels .IReliableFactorySettings
DatagramAdapter+DatagramAdapterListenerB ase<TChannel,TSessionChannel,ItemType >+IWaiter 0 1 type 1 method System.ServiceModel.Channels .DatagramAdapter+DatagramAdapterListener Base<TChannel,TSessionChannel,ItemType >+IWaiter
IMergeEnabledMessageProperty 1 1 type 1 method System.ServiceModel.Channels .IMergeEnabledMessageProperty
IBufferedMessageData 0.27 10 types 9 methods System.ServiceModel.Channels .IBufferedMessageData
ICompressedMessageEncoder 0.67 4 types 3 methods System.ServiceModel.Channels .ICompressedMessageEncoder
ITransportCompressionSupport 0.33 3 types 1 method System.ServiceModel.Channels .ITransportCompressionSupport
IPeerNeighbor 0.11 18 types 18 methods System.ServiceModel.Channels .IPeerNeighbor
IPeerFactory 0.28 4 types 8 methods System.ServiceModel.Channels .IPeerFactory
IFlooderForThrottle 0.5 1 type 2 methods System.ServiceModel.Channels .IFlooderForThrottle
IPeerMaintainer 1 1 type 17 methods System.ServiceModel.Channels .IPeerMaintainer
IConnectAlgorithms 1 1 type 4 methods System.ServiceModel.Channels .IConnectAlgorithms
IPeerNodeMessageHandling 0.071 6 types 7 methods System.ServiceModel.Channels .IPeerNodeMessageHandling
IPeerConnectorContract 0.5 2 types 4 methods System.ServiceModel.Channels .IPeerConnectorContract
IPeerFlooderContract<TFloodContract ,TLinkContract> 0.5 2 types 3 methods System.ServiceModel.Channels .IPeerFlooderContract<TFloodContract ,TLinkContract>
IPeerServiceContract 0.2 1 type 10 methods System.ServiceModel.Channels .IPeerServiceContract
ITransactionChannel 0.25 1 type 4 methods System.ServiceModel.Channels .ITransactionChannel
WSTrustDec2005+DriverDec2005+IWsTrustDec 2005SecurityTokenService 0 2 types 1 method System.ServiceModel.Security .WSTrustDec2005+DriverDec2005+IWsTrustDe c2005SecurityTokenService
WSTrustFeb2005+DriverFeb2005+IWsTrustFeb 2005SecurityTokenService 0 2 types 1 method System.ServiceModel.Security .WSTrustFeb2005+DriverFeb2005+IWsTrustFe b2005SecurityTokenService
IChannelSecureConversationSessionSetting s 0 1 type 6 methods System.ServiceModel.Security .IChannelSecureConversationSessionSettin gs
IListenerSecureConversationSessionSettin gs 0 1 type 12 methods System.ServiceModel.Security .IListenerSecureConversationSessionSetti ngs
ISecurityCommunicationObject 1 1 type 14 methods System.ServiceModel.Security .ISecurityCommunicationObject
TimeBoundedCache+IExpirableItem 0.5 4 types 1 method System.ServiceModel.Security .TimeBoundedCache+IExpirableItem
ISecurityContextSecurityTokenCacheProvid er 1 2 types 1 method System.ServiceModel.Security.Tokens .ISecurityContextSecurityTokenCacheProvi der
IAspNetMessageProperty 0.17 6 types 4 methods System.ServiceModel.Activation .IAspNetMessageProperty
IConnectionDuplicator 1 1 type 2 methods System.ServiceModel.Activation .IConnectionDuplicator
IConnectionRegister 0.67 1 type 3 methods System.ServiceModel.Activation .IConnectionRegister
IConnectionRegisterAsync 0.5 2 types 2 methods System.ServiceModel.Activation .IConnectionRegisterAsync
ListenerUnsafeNativeMethods+ICorRuntimeH ost 0.045 2 types 11 methods System.ServiceModel.Activation .ListenerUnsafeNativeMethods+ICorRuntime Host
IAnnouncementInnerClient 0.25 4 types 19 methods System.ServiceModel.Discovery .IAnnouncementInnerClient
IAnnouncementServiceImplementation 0 6 types 5 methods System.ServiceModel.Discovery .IAnnouncementServiceImplementation
IDiscoveryInnerClient 0.25 4 types 12 methods System.ServiceModel.Discovery .IDiscoveryInnerClient
IDiscoveryInnerClientResponse 0.42 8 types 5 methods System.ServiceModel.Discovery .IDiscoveryInnerClientResponse
IDiscoveryServiceImplementation 0 10 types 6 methods System.ServiceModel.Discovery .IDiscoveryServiceImplementation
IDiscoveryVersionImplementation 0.14 10 types 11 methods System.ServiceModel.Discovery .IDiscoveryVersionImplementation
IMulticastSuppressionImplementation 0 6 types 4 methods System.ServiceModel.Discovery .IMulticastSuppressionImplementation
IAnnouncementContractCD1 0.5 2 types 6 methods System.ServiceModel.Discovery.VersionCD1 .IAnnouncementContractCD1
IDiscoveryContractAdhocCD1 0.33 3 types 6 methods System.ServiceModel.Discovery.VersionCD1 .IDiscoveryContractAdhocCD1
IDiscoveryContractManagedCD1 0.5 2 types 6 methods System.ServiceModel.Discovery.VersionCD1 .IDiscoveryContractManagedCD1
IDiscoveryResponseContractCD1 0.67 2 types 6 methods System.ServiceModel.Discovery.VersionCD1 .IDiscoveryResponseContractCD1
IAnnouncementContractApril2005 0.5 2 types 6 methods System.ServiceModel.Discovery .VersionApril2005 .IAnnouncementContractApril2005
IDiscoveryContractApril2005 1 1 type 6 methods System.ServiceModel.Discovery .VersionApril2005 .IDiscoveryContractApril2005
IDiscoveryResponseContractApril2005 0.67 2 types 6 methods System.ServiceModel.Discovery .VersionApril2005 .IDiscoveryResponseContractApril2005
IAnnouncementContract11 0.5 2 types 6 methods System.ServiceModel.Discovery.Version11 .IAnnouncementContract11
IDiscoveryContractAdhoc11 0.33 3 types 6 methods System.ServiceModel.Discovery.Version11 .IDiscoveryContractAdhoc11
IDiscoveryContractManaged11 0.5 2 types 6 methods System.ServiceModel.Discovery.Version11 .IDiscoveryContractManaged11
IDiscoveryResponseContract11 0.67 2 types 6 methods System.ServiceModel.Discovery.Version11 .IDiscoveryResponseContract11
IUdpReceiveHandler 1 1 type 3 methods System.ServiceModel.Channels .IUdpReceiveHandler
IServiceModelActivationHandler 0.5 2 types 1 method System.ServiceModel.Activation .IServiceModelActivationHandler
IMSAdminBase 0.097 1 type 31 methods System.ServiceModel.Activation .IMSAdminBase
ICanonicalizableNode 0.33 3 types 4 methods System.Security.Cryptography.Xml .ICanonicalizableNode
IStorageFolderHandleAccess 1 1 type 1 method System.IO.IStorageFolderHandleAccess
IStorageItemHandleAccess 1 1 type 1 method System.IO.IStorageItemHandleAccess
IDispatcherQueue 0.17 2 types 3 methods System.Threading.IDispatcherQueue
IBufferByteAccess 1 1 type 1 method System.Runtime.InteropServices .WindowsRuntime.IBufferByteAccess
IRestrictedErrorInfo 1 1 type 2 methods System.Runtime.InteropServices .WindowsRuntime.IRestrictedErrorInfo
ISerParser 0.5 2 types 1 method System.Runtime.Serialization.Formatters .Soap.ISerParser
IDataNode 0.15 10 types 18 methods System.Runtime.Serialization.IDataNode
IGenericNameProvider 0 2 types 6 methods System.Runtime.Serialization .IGenericNameProvider
IByteBufferPool 0.23 15 types 2 methods System.IO.IByteBufferPool
WsdlParser+IDump 1 1 type 1 method System.Runtime.Remoting.MetadataServices .WsdlParser+IDump
WsdlParser+INamespaces 0 1 type 1 method System.Runtime.Remoting.MetadataServices .WsdlParser+INamespaces
ICancelable 1 1 type 1 method System.Runtime.ICancelable
IPersistencePipelineModule 0.16 8 types 11 methods System.Runtime .IPersistencePipelineModule
IDurableInstancingOptions 1 1 type 1 method System.Runtime.DurableInstancing .IDurableInstancingOptions
IPersistStream 0 2 types 5 methods System.Messaging.Interop.IPersistStream
IPersistStreamInit 0.17 1 type 6 methods System.Messaging.Interop .IPersistStreamInit
IStream 0 2 types 11 methods System.Messaging.Interop.IStream
ITransaction 0.17 4 types 3 methods System.Messaging.Interop.ITransaction
IWbemPathKeyList 0.2 1 type 10 methods WmiNative.IWbemPathKeyList
IWbemPath 0.15 1 type 26 methods WmiNative.IWbemPath
IWbemDecoupledRegistrar 1 1 type 2 methods WmiNative.IWbemDecoupledRegistrar
IWbemServices 0.043 1 type 23 methods WmiNative.IWbemServices
IWbemClassObject 0.065 7 types 24 methods WmiNative.IWbemClassObject
IWbemContext 0 4 types 9 methods WmiNative.IWbemContext
IWbemProviderInitSink 0.5 2 types 1 method WmiNative.IWbemProviderInitSink
IWbemObjectSink 0.33 3 types 2 methods WmiNative.IWbemObjectSink
IEnumWbemClassObject 0 2 types 5 methods WmiNative.IEnumWbemClassObject
IWbemQualifierSet 0.14 1 type 7 methods WmiNative.IWbemQualifierSet
ICIMResultHandler 0.2 3 types 5 methods System.Management.Instrumentation .ICIMResultHandler
ICIMQuery 0 1 type 1 method System.Management.Instrumentation .ICIMQuery
ICIMEnumerate 0.5 2 types 1 method System.Management.Instrumentation .ICIMEnumerate
ICIMGet 0.5 2 types 1 method System.Management.Instrumentation .ICIMGet
ICIMDelete 0.5 2 types 1 method System.Management.Instrumentation .ICIMDelete
ICIMUpdate 0.5 2 types 1 method System.Management.Instrumentation .ICIMUpdate
ICIMExecute 0.5 2 types 1 method System.Management.Instrumentation .ICIMExecute
ICIMCapabilities 0.83 1 type 6 methods System.Management.Instrumentation .ICIMCapabilities
IWbemClassObject_DoNotMarshal 0 5 types 24 methods System.Management .IWbemClassObject_DoNotMarshal
IWbemLocator 0 1 type 1 method System.Management.IWbemLocator
IWbemContext 0.014 16 types 9 methods System.Management.IWbemContext
IWbemServices 0.041 19 types 23 methods System.Management.IWbemServices
IWbemCallResult 0.5 1 type 4 methods System.Management.IWbemCallResult
IWbemObjectSink 0.11 9 types 2 methods System.Management.IWbemObjectSink
IEnumWbemClassObject 0.053 15 types 5 methods System.Management.IEnumWbemClassObject
IWbemObjectTextSrc 0.5 1 type 2 methods System.Management.IWbemObjectTextSrc
IWbemStatusCodeText 0.5 1 type 2 methods System.Management.IWbemStatusCodeText
IWbemProviderInitSink 1 1 type 1 method System.Management.IWbemProviderInitSink
IWbemDecoupledRegistrar 1 1 type 2 methods System.Management .IWbemDecoupledRegistrar
IWbemPathKeyList 0.2 1 type 10 methods System.Management.IWbemPathKeyList
IWbemPath 0.46 1 type 26 methods System.Management.IWbemPath
IMetaDataDispenser 0.33 1 type 3 methods System.Management.Instrumentation .IMetaDataDispenser
IMetaDataImportInternalOnly 0.12 1 type 8 methods System.Management.Instrumentation .IMetaDataImportInternalOnly
ILog 1 1 type 7 methods System.IO.Log.ILog
IFileBasedLogInit 1 1 type 1 method System.IO.Log.IFileBasedLogInit
ISspiNegotiation 0.1 11 types 8 methods System.ServiceModel.Security .ISspiNegotiation
ISspiNegotiationInfo 1 1 type 1 method System.ServiceModel.Security .ISspiNegotiationInfo
IPrefixGenerator 0 2 types 1 method System.IdentityModel.IPrefixGenerator
ISecurityElement 0.29 7 types 3 methods System.IdentityModel.ISecurityElement
ISignatureValueSecurityElement 0 5 types 1 method System.IdentityModel .ISignatureValueSecurityElement
ICanonicalWriterEndRootElementCallback 1 1 type 1 method System.IdentityModel .ICanonicalWriterEndRootElementCallback
IIdentityInfo 1 1 type 1 method System.IdentityModel.Policy .IIdentityInfo
IClrStrongNameUsingIntPtr 0.24 1 type 25 methods Microsoft.Runtime.Hosting .IClrStrongNameUsingIntPtr
IClrStrongName 0.36 1 type 25 methods Microsoft.Runtime.Hosting.IClrStrongName
IGetContextProperties 0.33 1 type 3 methods System.EnterpriseServices .IGetContextProperties
IContextProperties 0.2 1 type 5 methods System.EnterpriseServices .IContextProperties
IObjectConstruct 0 1 type 1 method System.EnterpriseServices .IObjectConstruct
IObjectConstructString 1 2 types 1 method System.EnterpriseServices .IObjectConstructString
IObjectContext 0.12 2 types 8 methods System.EnterpriseServices.IObjectContext
IObjectContextInfo 0.4 1 type 5 methods System.EnterpriseServices .IObjectContextInfo
IObjectContextInfo2 0.38 1 type 8 methods System.EnterpriseServices .IObjectContextInfo2
IObjectControl 0 2 types 3 methods System.EnterpriseServices.IObjectControl
ITransactionProxy 0 1 type 7 methods System.EnterpriseServices .ITransactionProxy
ITransactionVoterBallotAsync2 0 1 type 1 method System.EnterpriseServices .ITransactionVoterBallotAsync2
ITransactionVoterNotifyAsync2 0.4 2 types 5 methods System.EnterpriseServices .ITransactionVoterNotifyAsync2
ISharedProperty 0.5 2 types 2 methods System.EnterpriseServices .ISharedProperty
ISharedPropertyGroup 0.5 2 types 4 methods System.EnterpriseServices .ISharedPropertyGroup
ISharedPropertyGroupManager 1 1 type 3 methods System.EnterpriseServices .ISharedPropertyGroupManager
IManagedObject 0 3 types 2 methods System.EnterpriseServices.IManagedObject
IContext 0.33 1 type 3 methods System.EnterpriseServices.IContext
IManagedObjectInfo 0 1 type 4 methods System.EnterpriseServices .IManagedObjectInfo
ITransactionProperty 0.077 1 type 13 methods System.EnterpriseServices .ITransactionProperty
ISecurityCallersColl 0.5 2 types 3 methods System.EnterpriseServices .ISecurityCallersColl
ISecurityIdentityColl 0.11 3 types 3 methods System.EnterpriseServices .ISecurityIdentityColl
ISecurityCallContext 0.33 2 types 6 methods System.EnterpriseServices .ISecurityCallContext
IConfigurationAttribute 0.83 2 types 3 methods System.EnterpriseServices .IConfigurationAttribute
ICreateTypeLib 0.1 1 type 10 methods System.EnterpriseServices.ICreateTypeLib
IConfigCallback 1 1 type 6 methods System.EnterpriseServices .IConfigCallback
ITransactionResourcePool 1 1 type 2 methods System.EnterpriseServices .ITransactionResourcePool
ICreateWithTipTransactionEx 1 1 type 1 method System.EnterpriseServices .ICreateWithTipTransactionEx
ICreateWithTransactionEx 1 1 type 1 method System.EnterpriseServices .ICreateWithTransactionEx
ICreateWithLocalTransaction 1 1 type 1 method System.EnterpriseServices .ICreateWithLocalTransaction
IAssemblyCache 0.4 1 type 5 methods System.EnterpriseServices.Internal .IAssemblyCache
ITypeLib2 0.071 1 type 14 methods System.EnterpriseServices.Internal .ITypeLib2
IFormatLogRecords 1 1 type 3 methods System.EnterpriseServices .CompensatingResourceManager .IFormatLogRecords
_IMonitorClerks 0.43 2 types 7 methods System.EnterpriseServices .CompensatingResourceManager ._IMonitorClerks
ICatalog 0.12 1 type 26 methods System.EnterpriseServices.Admin.ICatalog
ICatalogObject 0.21 29 types 7 methods System.EnterpriseServices.Admin .ICatalogObject
ICatalogCollection 0.26 7 types 16 methods System.EnterpriseServices.Admin .ICatalogCollection
IThunkInstallation 1 1 type 1 method System.EnterpriseServices.Thunk .IThunkInstallation
IProxyInvoke 0.5 1 type 2 methods System.EnterpriseServices.Thunk .IProxyInvoke
IDispatch 0.21 6 types 4 methods System.Dynamic.IDispatch
IProvideClassInfo 1 1 type 1 method System.Dynamic.IProvideClassInfo
ISystemColorTracker 1 1 type 1 method System.Drawing.Internal .ISystemColorTracker
UnsafeNativeMethods+IMarshal 0 1 type 6 methods Microsoft.Win32 .UnsafeNativeMethods+IMarshal
IInternetSecurityManager 0.12 2 types 8 methods Microsoft.Win32.IInternetSecurityManager
IAuthenticationManager 1 1 type 14 methods System.Net.IAuthenticationManager
IWebProxyFinder 1 1 type 4 methods System.Net.IWebProxyFinder
IRequestLifetimeTracker 1 1 type 1 method System.Net.IRequestLifetimeTracker
ISessionAuthenticationModule 0.67 1 type 3 methods System.Net.ISessionAuthenticationModule
ICloseEx 1 6 types 1 method System.Net.ICloseEx
SSPIInterface 0.2 5 types 21 methods System.Net.SSPIInterface
IAutoWebProxy 1 1 type 1 method System.Net.IAutoWebProxy
IEncodableStream 0.42 3 types 4 methods System.Net.Mime.IEncodableStream
IMSAdminBase 0.13 1 type 31 methods System.Net.Mail.IMSAdminBase
ISmtpAuthenticationModule 0.4 5 types 3 methods System.Net.Mail .ISmtpAuthenticationModule
INotifyCollectionChangedEventArgs 1 1 type 5 methods System.Runtime.InteropServices .WindowsRuntime .INotifyCollectionChangedEventArgs
IPropertyChangedEventArgs 1 1 type 1 method System.Runtime.InteropServices .WindowsRuntime .IPropertyChangedEventArgs
INotifyCollectionChanged_WinRT 1 1 type 2 methods System.Runtime.InteropServices .WindowsRuntime .INotifyCollectionChanged_WinRT
INotifyPropertyChanged_WinRT 1 1 type 2 methods System.Runtime.InteropServices .WindowsRuntime .INotifyPropertyChanged_WinRT
ICommand_WinRT 1 1 type 4 methods System.Runtime.InteropServices .WindowsRuntime.ICommand_WinRT
IDeflater 1 1 type 4 methods System.IO.Compression.IDeflater
IInflater 0.6 1 type 5 methods System.IO.Compression.IInflater
IFileFormatWriter 0.5 2 types 3 methods System.IO.Compression.IFileFormatWriter
IFileFormatReader 0.33 3 types 4 methods System.IO.Compression.IFileFormatReader
NativeComInterfaces+IAdsPathname 0.21 7 types 11 methods System.DirectoryServices.ActiveDirectory .NativeComInterfaces+IAdsPathname
NativeComInterfaces+IAdsProperty 0.042 2 types 24 methods System.DirectoryServices.ActiveDirectory .NativeComInterfaces+IAdsProperty
NativeComInterfaces+IAdsClass 0.058 2 types 43 methods System.DirectoryServices.ActiveDirectory .NativeComInterfaces+IAdsClass
ILocationReport 0.67 1 type 3 methods System.Device.Location.Internal .ILocationReport
ILatLongReport 0.62 1 type 8 methods System.Device.Location.Internal .ILatLongReport
ILocation 0.67 1 type 9 methods System.Device.Location.Internal .ILocation
IWizardStepEditableRegion 1 2 types 1 method System.Web.UI.Design.WebControls .IWizardStepEditableRegion
IDesignConnection 0.046 14 types 14 methods System.Data.Design.IDesignConnection
IDataSourceNamedObject 0 5 types 1 method System.Data.Design .IDataSourceNamedObject
IDataSourceXmlSerializable 1 1 type 2 methods System.Data.Design .IDataSourceXmlSerializable
IDataSourceXmlSpecialOwner 1 1 type 2 methods System.Data.Design .IDataSourceXmlSpecialOwner
IDataSourceInitAfterLoading 1 1 type 1 method System.Data.Design .IDataSourceInitAfterLoading
INamedObject 0.5 4 types 2 methods System.Data.Design.INamedObject
INamedObjectCollection 0 3 types 1 method System.Data.Design .INamedObjectCollection
INameService 0.083 8 types 6 methods System.Data.Design.INameService
IEventHandlerService 0.18 11 types 6 methods System.Windows.Forms.Design .IEventHandlerService
IMenuStatusHandler 1 1 type 2 methods System.Windows.Forms.Design .IMenuStatusHandler
IMouseHandler 0.5 2 types 6 methods System.Windows.Forms.Design .IMouseHandler
IOleDragClient 0.33 4 types 6 methods System.Windows.Forms.Design .IOleDragClient
IOverlayService 0.32 5 types 5 methods System.Windows.Forms.Design .IOverlayService
ISelectionUIHandler 0.5 2 types 13 methods System.Windows.Forms.Design .ISelectionUIHandler
ISelectionUIService 0.11 5 types 20 methods System.Windows.Forms.Design .ISelectionUIService
ISplitWindowService 0.5 2 types 2 methods System.Windows.Forms.Design .ISplitWindowService
ISupportInSituService 0.33 3 types 3 methods System.Windows.Forms.Design .ISupportInSituService
IClrStrongNameUsingIntPtr 0.24 1 type 25 methods Microsoft.Runtime.Hosting .IClrStrongNameUsingIntPtr
IClrStrongName 0.36 1 type 25 methods Microsoft.Runtime.Hosting.IClrStrongName
IEnumSTORE_ASSEMBLY_INSTALLATION_REFEREN CE 0 1 type 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_INSTALLATION_REFERE NCE
IEnumSTORE_DEPLOYMENT_METADATA 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA
IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY
IEnumSTORE_ASSEMBLY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY
IEnumSTORE_ASSEMBLY_FILE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_FILE
IEnumSTORE_CATEGORY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY
IEnumSTORE_CATEGORY_SUBCATEGORY 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_SUBCATEGORY
IEnumSTORE_CATEGORY_INSTANCE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_INSTANCE
IReferenceIdentity 0.12 13 types 4 methods System.Deployment.Internal.Isolation .IReferenceIdentity
IDefinitionIdentity 0.083 18 types 4 methods System.Deployment.Internal.Isolation .IDefinitionIdentity
IEnumIDENTITY_ATTRIBUTE 0.2 2 types 5 methods System.Deployment.Internal.Isolation .IEnumIDENTITY_ATTRIBUTE
IEnumDefinitionIdentity 0.25 4 types 4 methods System.Deployment.Internal.Isolation .IEnumDefinitionIdentity
IEnumReferenceIdentity 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumReferenceIdentity
IDefinitionAppId 0.083 20 types 6 methods System.Deployment.Internal.Isolation .IDefinitionAppId
IReferenceAppId 0.2 5 types 5 methods System.Deployment.Internal.Isolation .IReferenceAppId
IIdentityAuthority 0.22 3 types 18 methods System.Deployment.Internal.Isolation .IIdentityAuthority
IAppIdAuthority 0.16 2 types 16 methods System.Deployment.Internal.Isolation .IAppIdAuthority
IStore 0.19 5 types 20 methods System.Deployment.Internal.Isolation .IStore
IManifestParseErrorCallback 0 2 types 1 method System.Deployment.Internal.Isolation .IManifestParseErrorCallback
IManifestInformation 0.5 2 types 1 method System.Deployment.Internal.Isolation .IManifestInformation
IActContext 0.22 3 types 18 methods System.Deployment.Internal.Isolation .IActContext
IStateManager 0.25 1 type 4 methods System.Deployment.Internal.Isolation .IStateManager
ISection 0.21 7 types 4 methods System.Deployment.Internal.Isolation .ISection
ISectionWithStringKey 0.5 1 type 2 methods System.Deployment.Internal.Isolation .ISectionWithStringKey
ISectionWithReferenceIdentityKey 1 1 type 1 method System.Deployment.Internal.Isolation .ISectionWithReferenceIdentityKey
ISectionEntry 0 1 type 2 methods System.Deployment.Internal.Isolation .ISectionEntry
IEnumUnknown 0.25 3 types 4 methods System.Deployment.Internal.Isolation .IEnumUnknown
ICMS 0.064 5 types 22 methods System.Deployment.Internal.Isolation .Manifest.ICMS
IHashElementEntry 0.14 2 types 7 methods System.Deployment.Internal.Isolation .Manifest.IHashElementEntry
IFileEntry 0.067 1 type 15 methods System.Deployment.Internal.Isolation .Manifest.IFileEntry
IFileAssociationEntry 0.17 1 type 6 methods System.Deployment.Internal.Isolation .Manifest.IFileAssociationEntry
IAssemblyReferenceEntry 0.25 1 type 4 methods System.Deployment.Internal.Isolation .Manifest.IAssemblyReferenceEntry
IEntryPointEntry 0.17 1 type 6 methods System.Deployment.Internal.Isolation .Manifest.IEntryPointEntry
IDescriptionMetadataEntry 0.14 1 type 7 methods System.Deployment.Internal.Isolation .Manifest.IDescriptionMetadataEntry
IDeploymentMetadataEntry 0.17 1 type 6 methods System.Deployment.Internal.Isolation .Manifest.IDeploymentMetadataEntry
IDependentOSMetadataEntry 0.12 1 type 8 methods System.Deployment.Internal.Isolation .Manifest.IDependentOSMetadataEntry
ICompatibleFrameworksMetadataEntry 0.5 1 type 2 methods System.Deployment.Internal.Isolation .Manifest .ICompatibleFrameworksMetadataEntry
IMetadataSectionEntry 0.33 1 type 21 methods System.Deployment.Internal.Isolation .Manifest.IMetadataSectionEntry
ICompatibleFrameworkEntry 0.2 1 type 5 methods System.Deployment.Internal.Isolation .Manifest.ICompatibleFrameworkEntry
IManagedDeploymentServiceCom 0 2 types 7 methods System.Deployment.Application .IManagedDeploymentServiceCom
IDownloadNotification 0 2 types 2 methods System.Deployment.Application .IDownloadNotification
IMetaDataDispenser 0.33 1 type 3 methods System.Deployment.Application .IMetaDataDispenser
IMetaDataImport 0 1 type 62 methods System.Deployment.Application .IMetaDataImport
IMetaDataAssemblyImport 0.5 1 type 14 methods System.Deployment.Application .IMetaDataAssemblyImport
NativeMethods+IAssemblyCache 0.05 4 types 5 methods System.Deployment.Application .NativeMethods+IAssemblyCache
NativeMethods+IAssemblyEnum 0.17 2 types 3 methods System.Deployment.Application .NativeMethods+IAssemblyEnum
NativeMethods+IApplicationContext 0 2 types 5 methods System.Deployment.Application .NativeMethods+IApplicationContext
NativeMethods+IAssemblyName 0 2 types 9 methods System.Deployment.Application .NativeMethods+IAssemblyName
NativeMethods+ICorRuntimeHost 0.026 2 types 19 methods System.Deployment.Application .NativeMethods+ICorRuntimeHost
ISourceLineInfo 0.22 18 types 4 methods System.Xml.Xsl.ISourceLineInfo
IErrorHelper 0.38 4 types 2 methods System.Xml.Xsl.IErrorHelper
IXPathBuilder<Node> 0.6 3 types 10 methods System.Xml.Xsl.XPath.IXPathBuilder<Node>
IFocus 0.5 2 types 3 methods System.Xml.Xsl.XPath.IFocus
IXPathEnvironment 0.38 2 types 4 methods System.Xml.Xsl.XPath.IXPathEnvironment
IQilAnnotation 1 1 type 1 method System.Xml.Xsl.Qil.IQilAnnotation
RecordOutput 0.2 5 types 2 methods System.Xml.Xsl.XsltOld.RecordOutput
IStackFrame 0 1 type 5 methods System.Xml.Xsl.XsltOld.Debugger .IStackFrame
IXsltProcessor 0 1 type 2 methods System.Xml.Xsl.XsltOld.Debugger .IXsltProcessor
IXsltDebugger 0.12 8 types 3 methods System.Xml.Xsl.XsltOld.Debugger .IXsltDebugger
IDataService 0.12 28 types 15 methods System.Data.Services.IDataService
IProjectedResult 0.5 2 types 2 methods System.Data.Services.IProjectedResult
OperationSignatures+ILogicalSignatures 0 2 types 3 methods System.Data.Services.Parsing .OperationSignatures+ILogicalSignatures
OperationSignatures+IArithmeticSignature s 0 2 types 11 methods System.Data.Services.Parsing .OperationSignatures+IArithmeticSignatur es
OperationSignatures+IRelationalSignature s 0 2 types 9 methods System.Data.Services.Parsing .OperationSignatures+IRelationalSignatur es
OperationSignatures+INegationSignatures 0 2 types 11 methods System.Data.Services.Parsing .OperationSignatures+INegationSignatures
OperationSignatures+INotSignatures 0 2 types 3 methods System.Data.Services.Parsing .OperationSignatures+INotSignatures
OperationSignatures+IEnumerableSignature s 0 1 type 28 methods System.Data.Services.Parsing .OperationSignatures+IEnumerableSignatur es
IExceptionWriter 0.5 2 types 1 method System.Data.Services.Serializers .IExceptionWriter
IProjectionProvider 0.5 2 types 1 method System.Data.Services.Providers .IProjectionProvider
IDataServices 0.21 8 types 7 methods System.Data.Linq.Provider.IDataServices
IDeferredSourceFactory 0.25 2 types 2 methods System.Data.Linq.Provider .IDeferredSourceFactory
IProvider 0.14 10 types 18 methods System.Data.Linq.Provider.IProvider
ICompiledQuery 0.67 3 types 1 method System.Data.Linq.Provider.ICompiledQuery
IConnectionManager 0.25 2 types 2 methods System.Data.Linq.SqlClient .IConnectionManager
IConnectionUser 1 1 type 1 method System.Data.Linq.SqlClient .IConnectionUser
IObjectReader 0.33 3 types 1 method System.Data.Linq.SqlClient.IObjectReader
IObjectReaderSession 0.17 6 types 2 methods System.Data.Linq.SqlClient .IObjectReaderSession
IReaderProvider 0.17 3 types 2 methods System.Data.Linq.SqlClient .IReaderProvider
IObjectReaderFactory 0.14 7 types 2 methods System.Data.Linq.SqlClient .IObjectReaderFactory
IObjectReaderCompiler 1 1 type 2 methods System.Data.Linq.SqlClient .IObjectReaderCompiler
ICompiledSubQuery 0 6 types 1 method System.Data.Linq.SqlClient .ICompiledSubQuery
IEntityStateManager 0.3 4 types 5 methods System.Data.IEntityStateManager
IEntityStateEntry 0.11 25 types 14 methods System.Data.IEntityStateEntry
IEntityAdapter 0.33 3 types 7 methods System.Data.IEntityAdapter
ISqlFragment 0.33 3 types 1 method System.Data.SqlClient.SqlGen .ISqlFragment
IDbSpatialValue 0.5 4 types 8 methods System.Data.SqlClient.Internal .IDbSpatialValue
IObjectView 1 1 type 2 methods System.Data.Objects.IObjectView
IObjectViewData<T> 0.33 3 types 13 methods System.Data.Objects.IObjectViewData<T>
IChangeTrackingStrategy 0 4 types 4 methods System.Data.Objects.Internal .IChangeTrackingStrategy
IEntityKeyStrategy 0 4 types 3 methods System.Data.Objects.Internal .IEntityKeyStrategy
IPropertyAccessorStrategy 0 4 types 5 methods System.Data.Objects.Internal .IPropertyAccessorStrategy
IEntityWrapper 0.13 21 types 29 methods System.Data.Objects.Internal .IEntityWrapper
IRelationshipFixer 0.33 3 types 1 method System.Data.Objects.DataClasses .IRelationshipFixer
IBaseList<T> 0.18 19 types 3 methods System.Data.Metadata.Edm.IBaseList<T>
ITileQuery 1 1 type 1 method System.Data.Mapping.ViewGeneration .QueryRewriting.ITileQuery
IRelationship 0.24 9 types 7 methods System.Data.EntityModel .SchemaObjectModel.IRelationship
IRelationshipEnd 0.3 10 types 5 methods System.Data.EntityModel .SchemaObjectModel.IRelationshipEnd
ISchemaElementLookUpTable<T> 0.25 4 types 5 methods System.Data.EntityModel .SchemaObjectModel .ISchemaElementLookUpTable<T>
IGroupExpressionExtendedInfo 1 1 type 2 methods System.Data.Common.EntitySql .IGroupExpressionExtendedInfo
IGetAlternativeName 1 1 type 1 method System.Data.Common.EntitySql .IGetAlternativeName
ITypedGetters 0 3 types 35 methods Microsoft.SqlServer.Server.ITypedGetters
ITypedGettersV3 0.11 10 types 17 methods Microsoft.SqlServer.Server .ITypedGettersV3
ITypedSettersV3 0.2 5 types 17 methods Microsoft.SqlServer.Server .ITypedSettersV3
IXmlDataVirtualNode 0.75 1 type 4 methods System.Xml.IXmlDataVirtualNode
IFilter 0.11 9 types 1 method System.Data.IFilter
NativeMethods+ISourcesRowset 0.5 2 types 1 method System.Data.Common .NativeMethods+ISourcesRowset
NativeMethods+ITransactionJoin 0.17 3 types 2 methods System.Data.Common .NativeMethods+ITransactionJoin
UnsafeNativeMethods+ADORecordConstructio n 0.5 2 types 1 method System.Data.Common .UnsafeNativeMethods+ADORecordConstructi on
UnsafeNativeMethods+ADORecordsetConstruc tion 0.33 2 types 3 methods System.Data.Common .UnsafeNativeMethods+ADORecordsetConstru ction
UnsafeNativeMethods+Recordset15 0.027 2 types 55 methods System.Data.Common .UnsafeNativeMethods+Recordset15
UnsafeNativeMethods+_ADORecord 0.031 2 types 16 methods System.Data.Common .UnsafeNativeMethods+_ADORecord
UnsafeNativeMethods+IAccessor 0.1 5 types 4 methods System.Data.Common .UnsafeNativeMethods+IAccessor
UnsafeNativeMethods+IChapteredRowset 0.25 2 types 2 methods System.Data.Common .UnsafeNativeMethods+IChapteredRowset
UnsafeNativeMethods+IColumnsInfo 0.33 3 types 1 method System.Data.Common .UnsafeNativeMethods+IColumnsInfo
UnsafeNativeMethods+IColumnsRowset 0.33 3 types 2 methods System.Data.Common .UnsafeNativeMethods+IColumnsRowset
UnsafeNativeMethods+ICommandPrepare 0.5 2 types 1 method System.Data.Common .UnsafeNativeMethods+ICommandPrepare
UnsafeNativeMethods+ICommandProperties 0.33 3 types 2 methods System.Data.Common .UnsafeNativeMethods+ICommandProperties
UnsafeNativeMethods+ICommandText 0.15 4 types 5 methods System.Data.Common .UnsafeNativeMethods+ICommandText
UnsafeNativeMethods+ICommandWithParamete rs 0.17 2 types 3 methods System.Data.Common .UnsafeNativeMethods+ICommandWithParamet ers
UnsafeNativeMethods+IDBInfo 0.25 4 types 2 methods System.Data.Common .UnsafeNativeMethods+IDBInfo
UnsafeNativeMethods+IDBProperties 0.14 7 types 3 methods System.Data.Common .UnsafeNativeMethods+IDBProperties
UnsafeNativeMethods+IDBSchemaRowset 0.2 5 types 2 methods System.Data.Common .UnsafeNativeMethods+IDBSchemaRowset
UnsafeNativeMethods+IErrorInfo 0.21 8 types 3 methods System.Data.Common .UnsafeNativeMethods+IErrorInfo
UnsafeNativeMethods+IErrorRecords 0.17 3 types 6 methods System.Data.Common .UnsafeNativeMethods+IErrorRecords
UnsafeNativeMethods+IMultipleResults 0.33 3 types 1 method System.Data.Common .UnsafeNativeMethods+IMultipleResults
UnsafeNativeMethods+IOpenRowset 0.33 3 types 1 method System.Data.Common .UnsafeNativeMethods+IOpenRowset
UnsafeNativeMethods+IRow 0.5 2 types 1 method System.Data.Common .UnsafeNativeMethods+IRow
UnsafeNativeMethods+IRowset 0.2 3 types 5 methods System.Data.Common .UnsafeNativeMethods+IRowset
UnsafeNativeMethods+IRowsetInfo 0.33 3 types 2 methods System.Data.Common .UnsafeNativeMethods+IRowsetInfo
UnsafeNativeMethods+ISQLErrorInfo 0.5 2 types 1 method System.Data.Common .UnsafeNativeMethods+ISQLErrorInfo
UnsafeNativeMethods+ITransactionLocal 0.05 4 types 5 methods System.Data.Common .UnsafeNativeMethods+ITransactionLocal
ICngSymmetricAlgorithm 1 1 type 13 methods Internal.Cryptography .ICngSymmetricAlgorithm
IIListProvider<TElement> 0.33 1 type 3 methods System.Linq.IIListProvider<TElement>
IParallelPartitionable<T> 1 1 type 1 method System.Linq.Parallel .IParallelPartitionable<T>
IMergeHelper<TInputOutput> 1 1 type 3 methods System.Linq.Parallel.IMergeHelper <TInputOutput>
IPartitionedStreamRecipient<TElement> 0.94 34 types 1 method System.Linq.Parallel .IPartitionedStreamRecipient<TElement>
IAttributedImport 0.33 3 types 6 methods System.ComponentModel.Composition .IAttributedImport
IReflectionPartCreationInfo 0.33 3 types 8 methods System.ComponentModel.Composition .ReflectionModel .IReflectionPartCreationInfo
IPartCreatorImportDefinition 1 5 types 1 method System.ComponentModel.Composition .Primitives.IPartCreatorImportDefinition
FilteredCatalog+IComposablePartCatalogTr aversal 1 1 type 2 methods System.ComponentModel.Composition .Hosting .FilteredCatalog+IComposablePartCatalogT raversal
IActivityDelegateFactory 1 1 type 2 methods System.Activities.Presentation .IActivityDelegateFactory
IExpandChild 0 1 type 1 method System.Activities.Presentation .IExpandChild
IAutoSplitContainer 1 1 type 2 methods System.Activities.Presentation .FreeFormEditing.IAutoSplitContainer
INestedFreeFormPanelContainer 0.75 2 types 2 methods System.Activities.Presentation .FreeFormEditing .INestedFreeFormPanelContainer
IAutoConnectContainer 0.33 3 types 2 methods System.Activities.Presentation .FreeFormEditing.IAutoConnectContainer
IAnnotationVisualProvider 0.25 4 types 3 methods System.Activities.Presentation .Annotations.IAnnotationVisualProvider
IAnnotationIndicator 0.2 5 types 4 methods System.Activities.Presentation .Annotations.IAnnotationIndicator
IDockedAnnotation 0.25 4 types 5 methods System.Activities.Presentation .Annotations.IDockedAnnotation
IFloatingAnnotation 0.23 4 types 13 methods System.Activities.Presentation .Annotations.IFloatingAnnotation
IValidationErrorSourceLocator 0.33 3 types 2 methods System.Activities.Presentation .Validation .IValidationErrorSourceLocator
IItemsCollection 0.5 1 type 4 methods System.Activities.Presentation.Model .IItemsCollection
IModelTreeItem 0.14 27 types 12 methods System.Activities.Presentation.Model .IModelTreeItem
IPropertyViewManager 0.22 3 types 6 methods System.Activities.Presentation.Internal .PropertyEditing.Views .IPropertyViewManager
ISelectionPathInterpreter 1 1 type 2 methods System.Activities.Presentation.Internal .PropertyEditing.Selection .ISelectionPathInterpreter
ISelectionStop 0.27 6 types 5 methods System.Activities.Presentation.Internal .PropertyEditing.Selection .ISelectionStop
IStateContainer 1 1 type 2 methods System.Activities.Presentation.Internal .PropertyEditing.State.IStateContainer
IAutomationFocusChangedEventSource 1 2 types 1 method System.Activities.Presentation.Internal .PropertyEditing.Automation .IAutomationFocusChangedEventSource
IMessageLogger 0.22 3 types 3 methods System.Activities.Presentation.Internal .PropertyEditing.FromExpression .Framework.IMessageLogger
IIconProvider 1 1 type 1 method System.Activities.Presentation.Internal .PropertyEditing.FromExpression .Framework.ValueEditors.IIconProvider
IPropertyInspector 0.25 2 types 2 methods System.Activities.Presentation.Internal .PropertyEditing.FromExpression .Framework.PropertyInspector .IPropertyInspector
IVersionEditor 1 1 type 1 method System.Activities.Presentation.View .IVersionEditor
ITreeViewItemSelectionHandler 0.5 3 types 2 methods System.Activities.Presentation.View .TreeView.ITreeViewItemSelectionHandler
IWorkflowDesignerXamlHelperExecutionCont ext 1 1 type 10 methods Microsoft.Activities.Presentation.Xaml .IWorkflowDesignerXamlHelperExecutionCon text
ILoadRetryStrategy 0.5 2 types 1 method System.Activities.DurableInstancing .ILoadRetryStrategy
IObjectSerializer 0.35 5 types 4 methods System.Activities.DurableInstancing .IObjectSerializer
IAsyncCodeActivity 1 1 type 1 method System.Activities.IAsyncCodeActivity
IDynamicActivity 0.33 2 types 3 methods System.Activities.IDynamicActivity
ILocationReferenceExpression 1 1 type 1 method System.Activities.Expressions .ILocationReferenceExpression
ILocationReferenceWrapper 1 3 types 1 method System.Activities.Expressions .ILocationReferenceWrapper
DynamicUpdateMapBuilder+IDefinitionMatch er 0.25 4 types 4 methods System.Activities.DynamicUpdate .DynamicUpdateMapBuilder+IDefinitionMatc her
IInstanceUpdatable 1 1 type 1 method System.Activities.DynamicUpdate .IInstanceUpdatable
IFlowSwitch 1 1 type 2 methods System.Activities.Statements.IFlowSwitch
ICaseKeyBoxView 0.88 1 type 8 methods System.Activities.Core.Presentation .ICaseKeyBoxView
IFlowSwitchLink 0.33 2 types 9 methods System.Activities.Core.Presentation .IFlowSwitchLink
IFlowSwitchDefaultLink 1 1 type 2 methods System.Activities.Core.Presentation .IFlowSwitchDefaultLink
IActivationService 0.5 2 types 5 methods System.ServiceModel.Activation .IActivationService
IActivatedMessageQueue 0.33 3 types 9 methods System.ServiceModel.Activation .IActivatedMessageQueue
ICreateITypeLib 0.1 1 type 10 methods Microsoft.Tools.RegAsm.ICreateITypeLib
IAssemblyEnum 0.17 2 types 3 methods Microsoft.Win32.IAssemblyEnum
IApplicationContext 0 2 types 5 methods Microsoft.Win32.IApplicationContext
IAssemblyName 0.056 2 types 9 methods Microsoft.Win32.IAssemblyName
IClrStrongNameUsingIntPtr 0.24 1 type 25 methods Microsoft.Runtime.Hosting .IClrStrongNameUsingIntPtr
IClrStrongName 0.36 1 type 25 methods Microsoft.Runtime.Hosting.IClrStrongName
IAsyncCausalityTracerStatics 0.86 1 type 7 methods Windows.Foundation.Diagnostics .IAsyncCausalityTracerStatics
IWellKnownStringEqualityComparer 1 1 type 2 methods System.IWellKnownStringEqualityComparer
IRuntimeMethodInfo 0.24 21 types 1 method System.IRuntimeMethodInfo
IRuntimeFieldInfo 0.67 6 types 1 method System.IRuntimeFieldInfo
IResourceGroveler 1 1 type 2 methods System.Resources.IResourceGroveler
ISecurityElementFactory 0.5 2 types 4 methods System.Security.ISecurityElementFactory
IBuiltInPermission 1 1 type 1 method System.Security.Permissions .IBuiltInPermission
IUnionSemanticCodeGroup 0 1 type 1 method System.Security.Policy .IUnionSemanticCodeGroup
ILegacyEvidenceAdapter 1 1 type 2 methods System.Security.Policy .ILegacyEvidenceAdapter
IDelayEvaluatedEvidence 0.33 8 types 3 methods System.Security.Policy .IDelayEvaluatedEvidence
IReportMatchMembershipCondition 1 2 types 1 method System.Security.Policy .IReportMatchMembershipCondition
IRuntimeEvidenceFactory 0.5 2 types 3 methods System.Security.Policy .IRuntimeEvidenceFactory
Tokenizer+ITokenReader 1 1 type 1 method System.Security.Util .Tokenizer+ITokenReader
IAsyncLocal 0.11 9 types 1 method System.Threading.IAsyncLocal
IAsyncLocalValueMap 0.5 3 types 2 methods System.Threading.IAsyncLocalValueMap
IDeferredDisposable 1 1 type 1 method System.Threading.IDeferredDisposable
IThreadPoolWorkItem 0.12 8 types 2 methods System.Threading.IThreadPoolWorkItem
ITaskCompletionAction 0.67 3 types 1 method System.Threading.Tasks .ITaskCompletionAction
IProducerConsumerQueue<T> 0.25 4 types 5 methods System.Threading.Tasks .IProducerConsumerQueue<T>
ISection 0.083 6 types 4 methods System.Deployment.Internal.Isolation .ISection
ISectionWithStringKey 0.5 1 type 2 methods System.Deployment.Internal.Isolation .ISectionWithStringKey
ISectionWithReferenceIdentityKey 1 1 type 1 method System.Deployment.Internal.Isolation .ISectionWithReferenceIdentityKey
ISectionEntry 0 2 types 2 methods System.Deployment.Internal.Isolation .ISectionEntry
IEnumUnknown 0.25 1 type 4 methods System.Deployment.Internal.Isolation .IEnumUnknown
IEnumSTORE_ASSEMBLY_INSTALLATION_REFEREN CE 0 1 type 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_INSTALLATION_REFERE NCE
IEnumSTORE_DEPLOYMENT_METADATA 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA
IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_DEPLOYMENT_METADATA_PROPERTY
IEnumSTORE_ASSEMBLY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY
IEnumSTORE_ASSEMBLY_FILE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_ASSEMBLY_FILE
IEnumSTORE_CATEGORY 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY
IEnumSTORE_CATEGORY_SUBCATEGORY 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_SUBCATEGORY
IEnumSTORE_CATEGORY_INSTANCE 0.17 3 types 4 methods System.Deployment.Internal.Isolation .IEnumSTORE_CATEGORY_INSTANCE
IReferenceIdentity 0 5 types 4 methods System.Deployment.Internal.Isolation .IReferenceIdentity
IDefinitionIdentity 0.021 12 types 4 methods System.Deployment.Internal.Isolation .IDefinitionIdentity
IEnumDefinitionIdentity 0.25 2 types 4 methods System.Deployment.Internal.Isolation .IEnumDefinitionIdentity
IDefinitionAppId 0.046 18 types 6 methods System.Deployment.Internal.Isolation .IDefinitionAppId
IReferenceAppId 0 2 types 5 methods System.Deployment.Internal.Isolation .IReferenceAppId
IIdentityAuthority 0.028 2 types 18 methods System.Deployment.Internal.Isolation .IIdentityAuthority
IAppIdAuthority 0.062 4 types 16 methods System.Deployment.Internal.Isolation .IAppIdAuthority
IStore 0.19 5 types 20 methods System.Deployment.Internal.Isolation .IStore
IManifestParseErrorCallback 0 2 types 1 method System.Deployment.Internal.Isolation .IManifestParseErrorCallback
IManifestInformation 0.5 2 types 1 method System.Deployment.Internal.Isolation .IManifestInformation
IActContext 0.14 2 types 18 methods System.Deployment.Internal.Isolation .IActContext
ICMS 0.053 6 types 22 methods System.Deployment.Internal.Isolation .Manifest.ICMS
IAssemblyReferenceDependentAssemblyEntry 0.091 1 type 11 methods System.Deployment.Internal.Isolation .Manifest .IAssemblyReferenceDependentAssemblyEntr y
IAssemblyReferenceEntry 0.25 1 type 4 methods System.Deployment.Internal.Isolation .Manifest.IAssemblyReferenceEntry
IEntryPointEntry 0.17 1 type 6 methods System.Deployment.Internal.Isolation .Manifest.IEntryPointEntry
IPermissionSetEntry 0.33 1 type 3 methods System.Deployment.Internal.Isolation .Manifest.IPermissionSetEntry
IDescriptionMetadataEntry 0.14 1 type 7 methods System.Deployment.Internal.Isolation .Manifest.IDescriptionMetadataEntry
IMetadataSectionEntry 0.048 2 types 21 methods System.Deployment.Internal.Isolation .Manifest.IMetadataSectionEntry
IInternalMessage 0.27 8 types 7 methods System.Runtime.Remoting.Messaging .IInternalMessage
ISerializationRootObject 1 1 type 1 method System.Runtime.Remoting.Messaging .ISerializationRootObject
NativeMethods+IDispatch 0 2 types 4 methods System.Runtime.InteropServices .NativeMethods+IDispatch
IRestrictedErrorInfo 0 2 types 2 methods System.Runtime.InteropServices .WindowsRuntime.IRestrictedErrorInfo
IClosable 1 1 type 1 method System.Runtime.InteropServices .WindowsRuntime.IClosable
IStringable 1 2 types 1 method System.Runtime.InteropServices .WindowsRuntime.IStringable
IReference<T> 0 1 type 1 method System.Runtime.InteropServices .WindowsRuntime.IReference<T>
IGetProxyTarget 1 1 type 1 method System.Runtime.InteropServices .WindowsRuntime.IGetProxyTarget
ICustomProperty 0 4 types 8 methods System.Runtime.InteropServices .WindowsRuntime.ICustomProperty
IIterable<T> 0.6 5 types 1 method System.Runtime.InteropServices .WindowsRuntime.IIterable<T>
IBindableIterable 1 1 type 1 method System.Runtime.InteropServices .WindowsRuntime.IBindableIterable
IIterator<T> 0.17 9 types 4 methods System.Runtime.InteropServices .WindowsRuntime.IIterator<T>
IBindableIterator 0.17 6 types 3 methods System.Runtime.InteropServices .WindowsRuntime.IBindableIterator
IVector<T> 0.27 4 types 12 methods System.Runtime.InteropServices .WindowsRuntime.IVector<T>
IVector_Raw<T> 0.83 1 type 12 methods System.Runtime.InteropServices .WindowsRuntime.IVector_Raw<T>
IVectorView<T> 0.38 6 types 4 methods System.Runtime.InteropServices .WindowsRuntime.IVectorView<T>
IBindableVector 0.33 3 types 10 methods System.Runtime.InteropServices .WindowsRuntime.IBindableVector
IBindableVectorView 0 1 type 3 methods System.Runtime.InteropServices .WindowsRuntime.IBindableVectorView
IMap<K,V> 0.29 3 types 7 methods System.Runtime.InteropServices .WindowsRuntime.IMap<K,V>
IMapView<K,V> 0.19 4 types 4 methods System.Runtime.InteropServices .WindowsRuntime.IMapView<K,V>
IKeyValuePair<K,V> 0.67 3 types 2 methods System.Runtime.InteropServices .WindowsRuntime.IKeyValuePair<K,V>
OpportunisticIntern+IInternable 0.6 3 types 5 methods Microsoft.Build .OpportunisticIntern+IInternable
INodeEndpoint 0 3 types 7 methods Microsoft.Build.BackEnd.INodeEndpoint
INodePacket 0.4 5 types 1 method Microsoft.Build.BackEnd.INodePacket
INodePacketHandler 0.5 2 types 1 method Microsoft.Build.BackEnd .INodePacketHandler
INodePacketTranslatable 1 2 types 1 method Microsoft.Build.BackEnd .INodePacketTranslatable
INodePacketTranslator 0.063 14 types 27 methods Microsoft.Build.BackEnd .INodePacketTranslator
IRecordEnum 1 1 type 1 method Microsoft.VisualBasic.CompilerServices .IRecordEnum
IRowsetInternal 0.3 2 types 5 methods Microsoft.VisualBasic.Compatibility.VB6 .IRowsetInternal
IRowsetChangeInternal 0.33 1 type 3 methods Microsoft.VisualBasic.Compatibility.VB6 .IRowsetChangeInternal
IDataFormatInternal 0.36 1 type 14 methods Microsoft.VisualBasic.Compatibility.VB6 .IDataFormatInternal
IScriptScope 0 2 types 1 method Microsoft.Compiler.VisualBasic .IScriptScope
ITypeScope 0 2 types 2 methods Microsoft.Compiler.VisualBasic .ITypeScope
IImportScope 0 2 types 1 method Microsoft.Compiler.VisualBasic .IImportScope
UCOMITransactionBridgeNetworkConfigXP 1 1 type 7 methods Microsoft.Transactions.Bridge.Dtc .UCOMITransactionBridgeNetworkConfigXP
UCOMITransactionBridgeNetworkConfig 1 1 type 8 methods Microsoft.Transactions.Bridge.Dtc .UCOMITransactionBridgeNetworkConfig
UCOMIGatewayProtocol 0.67 1 type 3 methods Microsoft.Transactions.Bridge.Dtc .UCOMIGatewayProtocol
IActivationCoordinator 0.2 5 types 1 method Microsoft.Transactions.Wsat.Messaging .IActivationCoordinator
ICompletionCoordinator 0.2 5 types 3 methods Microsoft.Transactions.Wsat.Messaging .ICompletionCoordinator
ICompletionParticipant 0.25 4 types 3 methods Microsoft.Transactions.Wsat.Messaging .ICompletionParticipant
IDatagramService 0 1 type 2 methods Microsoft.Transactions.Wsat.Messaging .IDatagramService
IRequestReplyService 0 4 types 3 methods Microsoft.Transactions.Wsat.Messaging .IRequestReplyService
IWSActivationCoordinator 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSActivationCoordinator
IWSRegistrationCoordinator 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSRegistrationCoordinator
IWSCompletionCoordinator 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSCompletionCoordinator
IWSCompletionParticipant 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSCompletionParticipant
IWSTwoPhaseCommitCoordinator 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSTwoPhaseCommitCoordinator
IWSTwoPhaseCommitParticipant 0.5 2 types 1 method Microsoft.Transactions.Wsat.Messaging .IWSTwoPhaseCommitParticipant
ICoordinationListener 0.33 5 types 3 methods Microsoft.Transactions.Wsat.Messaging .ICoordinationListener
IRegistrationCoordinator 0.2 5 types 1 method Microsoft.Transactions.Wsat.Messaging .IRegistrationCoordinator
ITwoPhaseCommitCoordinator 0.2 5 types 6 methods Microsoft.Transactions.Wsat.Messaging .ITwoPhaseCommitCoordinator
ITwoPhaseCommitParticipant 0.2 5 types 4 methods Microsoft.Transactions.Wsat.Messaging .ITwoPhaseCommitParticipant
ITimerRecipient 1 1 type 3 methods Microsoft.Transactions.Wsat.Protocol .ITimerRecipient
IProtocolProvider 0.3 3 types 9 methods Microsoft.Transactions.Bridge .IProtocolProvider
IProtocolProviderCoordinatorService 0.14 20 types 6 methods Microsoft.Transactions.Bridge .IProtocolProviderCoordinatorService
IProtocolProviderPropagationService 0.079 7 types 9 methods Microsoft.Transactions.Bridge .IProtocolProviderPropagationService
IProducerConsumerQueue<T> 0.6 2 types 5 methods System.Threading.Tasks .IProducerConsumerQueue<T>
IDataflowBlock 0.087 23 types 3 methods System.Threading.Tasks.Dataflow .IDataflowBlock
IReceivableSourceBlock<TOutput> 0.5 1 type 2 methods System.Threading.Tasks.Dataflow .IReceivableSourceBlock<TOutput>
ISourceBlock<TOutput> 0.13 29 types 4 methods System.Threading.Tasks.Dataflow .ISourceBlock<TOutput>
ITargetBlock<TInput> 0.11 35 types 1 method System.Threading.Tasks.Dataflow .ITargetBlock<TInput>
IDebuggerDisplay 1 6 types 1 method System.Threading.Tasks.Dataflow.Internal .IDebuggerDisplay
IReorderingBuffer 0.25 4 types 1 method System.Threading.Tasks.Dataflow.Internal .IReorderingBuffer
ICSharpInvokeOrInvokeMemberBinder 0.57 2 types 7 methods Microsoft.CSharp.RuntimeBinder .ICSharpInvokeOrInvokeMemberBinder
ITypeOrNamespace 0.2 5 types 4 methods Microsoft.CSharp.RuntimeBinder.Semantics .ITypeOrNamespace
IErrorSink 0.25 2 types 2 methods Microsoft.CSharp.RuntimeBinder.Errors .IErrorSink
IKeyed 1 1 type 1 method Microsoft.Build.Collections.IKeyed
IInternetSecurityManager 0.12 1 type 8 methods IInternetSecurityManager
IClrStrongNameUsingIntPtr 0.24 1 type 25 methods Microsoft.Runtime.Hosting .IClrStrongNameUsingIntPtr
IClrStrongName 0.36 1 type 25 methods Microsoft.Runtime.Hosting.IClrStrongName
OpportunisticIntern+IInternable 0.6 3 types 5 methods Microsoft.Build .OpportunisticIntern+IInternable
IComReferenceResolver 0.17 2 types 3 methods Microsoft.Build.Tasks .IComReferenceResolver
UCOMICreateITypeLib 0.1 1 type 10 methods Microsoft.Build.Tasks .UCOMICreateITypeLib
IMetaDataDispenser 0.33 1 type 3 methods Microsoft.Build.Tasks.IMetaDataDispenser
IMetaDataImport 0 2 types 62 methods Microsoft.Build.Tasks.IMetaDataImport
IMetaDataImport2 0.014 2 types 69 methods Microsoft.Build.Tasks.IMetaDataImport2
IMetaDataAssemblyImport 0.25 2 types 14 methods Microsoft.Build.Tasks .IMetaDataAssemblyImport
IAssemblyCache 0.1 2 types 5 methods Microsoft.Build.Tasks.IAssemblyCache
IAssemblyName 0.056 2 types 9 methods Microsoft.Build.Tasks.IAssemblyName
IAssemblyEnum 0.17 2 types 3 methods Microsoft.Build.Tasks.IAssemblyEnum
IEngineCallback 0.18 12 types 6 methods Microsoft.Build.BuildEngine .IEngineCallback
INodeProvider 0.3 3 types 10 methods Microsoft.Build.BuildEngine .INodeProvider
ITaskRegistry 0.22 6 types 3 methods Microsoft.Build.BuildEngine .ITaskRegistry
OpportunisticIntern+IInternable 0.26 7 types 5 methods Microsoft.Build .OpportunisticIntern+IInternable
IToolsetProvider 0.17 6 types 2 methods Microsoft.Build.Evaluation .IToolsetProvider
ConditionEvaluator+IConditionEvaluationS tate 0.22 7 types 7 methods Microsoft.Build.Evaluation .ConditionEvaluator+IConditionEvaluation State
IEvaluatorData<P,I,M,D> 0.43 2 types 38 methods Microsoft.Build.Evaluation .IEvaluatorData<P,I,M,D>
IItem 0.3 10 types 5 methods Microsoft.Build.Evaluation.IItem
IItemDefinition<M> 0.33 3 types 2 methods Microsoft.Build.Evaluation .IItemDefinition<M>
IItemFactory<S,T> 0.14 8 types 8 methods Microsoft.Build.Evaluation.IItemFactory <S,T>
IItem<M> 0.5 2 types 2 methods Microsoft.Build.Evaluation.IItem<M>
IItemProvider<T> 0.14 7 types 1 method Microsoft.Build.Evaluation.IItemProvider <T>
IMetadataTable 0.037 9 types 3 methods Microsoft.Build.Evaluation .IMetadataTable
IProjectMetadataParent 1 1 type 2 methods Microsoft.Build.Evaluation .IProjectMetadataParent
IProperty 0.33 10 types 3 methods Microsoft.Build.Evaluation.IProperty
IPropertyProvider<T> 0.1 10 types 2 methods Microsoft.Build.Evaluation .IPropertyProvider<T>
IKeyed 0.7 10 types 1 method Microsoft.Build.Collections.IKeyed
IDeepCloneable<T> 1 1 type 1 method Microsoft.Build.Collections .IDeepCloneable<T>
IValued 1 3 types 1 method Microsoft.Build.Collections.IValued
IElementLocation 0.042 48 types 4 methods Microsoft.Build.Shared.IElementLocation
INodeEndpoint 0.2 5 types 7 methods Microsoft.Build.BackEnd.INodeEndpoint
INodePacket 0.56 18 types 1 method Microsoft.Build.BackEnd.INodePacket
INodePacketFactory 0.31 4 types 4 methods Microsoft.Build.BackEnd .INodePacketFactory
INodePacketHandler 0.17 6 types 1 method Microsoft.Build.BackEnd .INodePacketHandler
INodePacketTranslatable 1 3 types 1 method Microsoft.Build.BackEnd .INodePacketTranslatable
INodePacketTranslator 0.091 45 types 27 methods Microsoft.Build.BackEnd .INodePacketTranslator
IConfigCache 0.29 7 types 11 methods Microsoft.Build.BackEnd.IConfigCache
IResultsCache 0.39 4 types 7 methods Microsoft.Build.BackEnd.IResultsCache
ITargetBuilderCallback 0.33 3 types 1 method Microsoft.Build.BackEnd .ITargetBuilderCallback
IRequestBuilder 0.26 3 types 9 methods Microsoft.Build.BackEnd.IRequestBuilder
IRequestBuilderCallback 0.42 2 types 6 methods Microsoft.Build.BackEnd .IRequestBuilderCallback
ITargetBuilder 1 1 type 1 method Microsoft.Build.BackEnd.ITargetBuilder
ITaskBuilder 0.5 2 types 1 method Microsoft.Build.BackEnd.ITaskBuilder
IBuildResults 0.44 1 type 9 methods Microsoft.Build.BackEnd.IBuildResults
IBuildRequestEngine 0.67 2 types 18 methods Microsoft.Build.BackEnd .IBuildRequestEngine
INodeManager 0.62 2 types 4 methods Microsoft.Build.BackEnd.INodeManager
INodeProvider 0.6 2 types 5 methods Microsoft.Build.BackEnd.INodeProvider
IBuildComponent 0.28 9 types 2 methods Microsoft.Build.BackEnd.IBuildComponent
IBuildComponentHost 0.19 26 types 6 methods Microsoft.Build.BackEnd .IBuildComponentHost
IScheduler 0.89 1 type 9 methods Microsoft.Build.BackEnd.IScheduler
INode 1 1 type 1 method Microsoft.Build.BackEnd.INode
ITaskExecutionHost 0.89 1 type 9 methods Microsoft.Build.BackEnd .ITaskExecutionHost
ILoggingService 0.053 31 types 48 methods Microsoft.Build.BackEnd.Logging .ILoggingService
IBuildEventSink 0.3 3 types 9 methods Microsoft.Build.BackEnd.Logging .IBuildEventSink
IRegisteredTaskObjectCache 0.42 3 types 4 methods Microsoft.Build.BackEnd.Components .Caching.IRegisteredTaskObjectCache
ICatalog2 0.088 1 type 57 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICatalog2
ICatalogObject 0.48 3 types 7 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICatalogObject
ICatalogCollection 0.29 3 types 16 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICatalogCollection
IPSFactoryBuffer 0.5 1 type 2 methods Microsoft.Tools.ServiceModel .ComSvcConfig.IPSFactoryBuffer
ICreateTypeLib 0.25 2 types 10 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICreateTypeLib
ICreateTypeInfo 0.13 1 type 23 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICreateTypeInfo
ICreateTypeInfo2 0.053 1 type 38 methods Microsoft.Tools.ServiceModel .ComSvcConfig.ICreateTypeInfo2
IEnumUnknown 0.25 1 type 4 methods Microsoft.Tools.ServiceModel .ComSvcConfig.IEnumUnknown
IClrMetaHost 0.17 1 type 6 methods Microsoft.Tools.ServiceModel .ComSvcConfig.IClrMetaHost
IClrRuntimeInfo 0.071 2 types 7 methods Microsoft.Tools.ServiceModel .ComSvcConfig.IClrRuntimeInfo

 

SOLID Design: The Open-Close Principle (OCP)

The Open-Close principle (OCP) is the O in the well known SOLID acronym.

Bertrand Meyer is generally credited for having originated the term open/closed principle, which appeared in his 1988 book Object Oriented Software Construction. Its original definition is

  • A module will be said to be open if it is still available for extension. For example, it should be possible to add fields to the data structures it contains, or new elements to the set of functions it performs.
  • A module will be said to be closed if it is available for use by other modules. This assumes that the module has been given a well-defined, stable description (the interface in the sense of information hiding)

Upon these definitions the principle is usually expressed and summarized this way:

Modules should be open for extension and closed for modification.

There have been (and still are) a lot of debates about the meaning of this simple definition and its implication on the usage of Object-Oriented Programming (OOP) in the real-world.

In this post I’ll try to be as concrete and concise as possible.

The classical code example to explain OCP

The classical code example to explain OCP can be translated in C# this way:

I find this example a bit gross. I believe one must have no idea of what OOP is to write such code. It can obviously be refactored to something like this:

Let’s look at the implication of this refactoring:

  • We introduced a new abstraction IShape to represent a concept that we already had in mind. Indeed, in the first code sample the method DrawShapes() already accepted a sequence of shapes. With the new IShape abstraction our design is now open to accept more shapes like Triangle or Pentagone.
  • The method DrawShapes() will draw any new shape without any need for modification. In other words the DrawShapes() method implementation is closed.

Here is how the OCP is usually presented. It is all about anticipating the future changes in the system in a way that:

  • When a change occurs existing code is left untouched. Existing code here is DrawShapes() concrete method body, IShape interface and Circle and Square classes.
  • When a change occurs new code to implement changes is written in new classes that implement existing abstraction. New classes here could be Triangle and Pentagone.

The Point of Variation principle

Another way to see the OCP is the Point of Variation (PV) principle that states:

Identify points of predicted variation and create a stable interface around them.

I find PV more understandable than OCP because it is actionable. First identify potential variations, second build the proper abstractions around these variations.

The real challenge: Anticipation

But the real challenge is anticipation, anticipating is hard. If anticipation was easy we’d be all billionaire in bitcoins. In real world, when you anticipate the risk is high that:

  1. We do anticipate variations that won’t vary. This is what the YAGNI principle says (You aren’t gonna need it): Always implement things when you actually need them, never when you just foresee that you need them. Developing and maintaining an abstraction has a cost and if we won’t need it this cost is negative.
  2. The risk is also high that we don’t anticipate the variation that will really be needed. But once the need for variation becomes real this is your developer responsibility to refactor and create the right abstractions and the right stable code that will act upon these abstractions. This is the fool me once, don’t fool me twice idea: I am not supposed to foresee what I’ll need but I am supposed to identify and then write the right abstraction when I need it.

OCP in the real world

Here is a pragmatic approach to OCP:

  • In any case the KISS principle applies (Keep It Simple Stupid): don’t underestimate the difficulty of anticipating and don’t waste your resources creating abstractions you won’t need.
  • Write automatic tests: one of the greatest benefit of writing tests is that for a while, you must look at your code from the client perspective. If your code contains some area difficult to cover by tests, it certainly means that your code should be refactored to be easily 100% testable. Experience shows that when refactoring from poorly testable code to fully testable code, the need for right abstractions naturally pops up.
  • Some static analyzers can help you pinpoint typical OCP violations:
    • when downcasting reference (i.e casting from a base class or interface to a subclass or leaf class.),
    • when using the is or as operators (as in the first example above).
    • NDepend has the rule Base class should not use derivatives: matches of this rules are obvious violation of the OCP.
  • Keep in mind the fool me once, don’t fool me twice idea. You must refactor code as soon as the need to abstract some concepts is identified. Of course sometime it is not possible if tons of client code depend upon your API: in this situation you cannot easily refactor and often you’ll have to live with wrong design. This is why public API design is such a sensitive topic: you have no other choice than doing your best to anticipate and to accept to live with your past design mistake.

Be open to more than one variation with the Visitor pattern

Finally let’s underline that in the real world, data objects (like the shapes here) don’t implement themselves algorithm such as drawing. Experience tells that this is a clear violation of OCP because when a new algorithm is needed on data objects, like persistence in addition of drawing for example, all shape classes must be modified again. This is also a violation of the Single Responsibility Principle (SRP, the S in SOLID) because a shape class has now two responsibilities: 1) holding the shape data 2) drawing the shape.

Hence we now have two variations: we  need a way to abstract both the shapes and the algorithms applied on the shapes, in order to to write something like algorithm.ApplyOn(shape). This sort of call on two abstractions is named a double dispatching call: the implementation really invoked depends both on the IShape object’s type and the IAlgorithm object’s type. If you have N shapes and M algorithms you need [N x M] implementations.

Fortunately the visitor pattern helps implementing double dispatching. The code with the new persistence algorithm would then look like:

 

 

 

Ensure that your classes are declared as sealed when possible

Inheritance is one of the pillar of OOP. However, in the real world, most classes are not designed to be properly inheritable.

Properly designing a class to be inheritable is a tricky task. One must anticipate state initialization, state correctness, state mutability and also non-public methods calls from descendants. Anticipating well code re-use is hard and this requires experience. As a consequence there is no chance that a class gets well designed for inheritance by chance.

However, in both C# and VB.NET, a class is by default inheritable. The C# keyword sealed and the VB.NET keyword NotInheritable must be specified explicitly. Since there is no compiler warning most developers don’t bother to seal their classes. Hence most classes are not properly designed for inheritance but are implicitly declared as inheritable.

As if writing high quality code was not complicated enough here we have a language pitfall.

This is why NDepend proposes the default rule Class with no descendant should be sealed if possible. The CQLinq source code of this rule is pretty obvious:

As explained in the rule’s comments, you won’t get warnings per default for public non-sealed classes with no descendants. Indeed, it might be well that the analyzed code base is a framework and that descendants of such classes are not available at the time of analysis. But if the code base analyzed is an application with no public API it is important to comment this clause and get most public classes declared as sealed.

If you are not convinced that most classes should be sealed, there are also non-obvious reasons. Here is a quote from Jeffrey Richter from his essential book CLR via C#:

When defining a new type, compilers should make the class sealed by default so that the class cannot be used as a base class. Instead, many compilers, including C#, default to unsealed classes and allow the programmer to explicitly mark a class as sealed by using the sealed keyword. Obviously, it is too late now, but I think that today’s compilers have chosen the wrong default and it would be nice if it could change with future compilers. There are three reasons why a sealed class is better than an unsealed class:

  • Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
  • Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
  • Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)

In the same vein you can also refer to this Eric Lippert 2004 post where he explains why most .NET Framework classes are sealed per default.

An in-depth analysis of .NET Core 3.0 support for WPF and Winforms APIs

.NET Core 3.0 will be RTM soon and it supports WPF and Winforms APIs.

In my last post I’ve been exploring .NET Core 3.0 new APIs by comparing compiled bits with NDepend, of .NET Core 3.0 against .NET Core 2.2.

In this post I will compare .NET Core 3.0 Windows Forms (Winforms) and WPF APIs with .NET Framework 4.x.

I won’t make the suspense last: .NET Core 3.0 support for Winforms and WPF APIs is almost complete, I found very few breaking changes.

I will now explain what I’ve done with NDepend to explore this API diff, and then dig into the results. If you are wondering How to port desktop applications to .NET Core 3.0 see Microsoft explanations here.

Comparing .NET Core 3.0 Winforms and WPF APIs vs. NET Framework 4.x with NDepend

From the NDepend Start Page select Compare 2 versions of a code base menu. Then use Add assemblies in Folder buttons to add .NET Framework assemblies from folder C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319 and Microsoft.WindowsDesktop.app nuget package assemblies (from folder C:\Users\psmac\.nuget\packages\microsoft.windowsdesktop.app\3.0.0-preview-27325-3\ref\netcoreapp3.0 on my machine).

Comparing .NET Core 3.0 Winforms WPF APIs with .NET Framework

A minor difficulty was to isolate the exact set of assemblies to focus on. Here is the list of concerned assemblies I came up with:

Notice that to preserve the correspondance between APIs and assemblies packaging, the attribute TypeForwardedToAttribute is massively used to delegate implementations.

Usage of TypeForwardedToAttribute

The few breaking changes

With the default NDepend rules about API breaking changes, I’ve only found 16 public types and 52 public methods missing. Here are the types:

16 types missing in WPF Winforms .NET Core 3.0 API

16 types missing on a total of 4.095 public types, well done!

Number of public types per assemblies

The 52 public methods missing are: (on a total of 42.645 public methods)

Parent Assembly Name Parent Type Name Method name
System.Security.Principal.Windows System.Security.Principal.WindowsIdentity .ctor(String,String)
System.Security.Principal.Windows System.Security.Principal.WindowsIdentity Impersonate()
System.Security.Principal.Windows System.Security.Principal.WindowsIdentity Impersonate(IntPtr)
System.Security.Principal.Windows System.Security.Principal.IdentityReferenceCollection get_IsReadOnly()
System.Security.Permissions System.Net.EndpointPermission ToString()
System.Security.Permissions System.Security.HostProtectionException GetObjectData(SerializationInfo,StreamingContext)
System.Security.Permissions System.Security.Policy.ApplicationDirectory Clone()
System.Security.Permissions System.Security.Policy.ApplicationTrust Clone()
System.Security.Permissions System.Security.Policy.PermissionRequestEvidence Clone()
System.Security.Permissions System.Security.Policy.Site Clone()
System.Security.Permissions System.Security.Policy.StrongName Clone()
System.Security.Permissions System.Security.Policy.Url Clone()
System.Security.Permissions System.Security.Policy.Zone Clone()
System.Security.Permissions System.Security.Policy.GacInstalled Clone()
System.Security.Permissions System.Security.Policy.Hash Clone()
System.Security.Permissions System.Security.Policy.Publisher Clone()
System.Security.Cryptography.Pkcs System.Security.Cryptography.Pkcs.EnvelopedCms .ctor(SubjectIdentifierType,ContentInfo)
System.Security.Cryptography.Pkcs System.Security.Cryptography.Pkcs.EnvelopedCms .ctor(SubjectIdentifierType,ContentInfo,AlgorithmIdentifier)
System.Security.Cryptography.Pkcs System.Security.Cryptography.Pkcs.EnvelopedCms Encrypt()
System.Security.Cryptography.Pkcs System.Security.Cryptography.Pkcs.ContentInfo Finalize()
System.Security.Cryptography.Cng System.Security.Cryptography.ECDiffieHellmanCng FromXmlString(String)
System.Security.Cryptography.Cng System.Security.Cryptography.ECDiffieHellmanCng ToXmlString(Boolean)
System.Security.Cryptography.Cng System.Security.Cryptography.ECDsaCng FromXmlString(String)
System.Security.Cryptography.Cng System.Security.Cryptography.ECDsaCng ToXmlString(Boolean)
System.Security.Cryptography.Cng System.Security.Cryptography.RSACng DecryptValue(Byte[])
System.Security.Cryptography.Cng System.Security.Cryptography.RSACng EncryptValue(Byte[])
System.Security.Cryptography.Cng System.Security.Cryptography.RSACng get_KeyExchangeAlgorithm()
System.Security.Cryptography.Cng System.Security.Cryptography.RSACng get_SignatureAlgorithm()
System.Printing System.Printing.PrintQueue set_Name(String)
System.Printing System.Printing.IndexedProperties.PrintInt32Property op_Implicit(PrintInt32Property)
System.Printing System.Printing.IndexedProperties.PrintStringProperty op_Implicit(PrintStringProperty)
System.Printing System.Printing.IndexedProperties.PrintStreamProperty op_Implicit(PrintStreamProperty)
System.Printing System.Printing.IndexedProperties.PrintQueueAttributeProperty op_Implicit(PrintQueueAttributeProperty)
System.Printing System.Printing.IndexedProperties.PrintQueueStatusProperty op_Implicit(PrintQueueStatusProperty)
System.Printing System.Printing.IndexedProperties.PrintBooleanProperty op_Implicit(PrintBooleanProperty)
System.Printing System.Printing.IndexedProperties.PrintThreadPriorityProperty op_Implicit(PrintThreadPriorityProperty)
System.Printing System.Printing.IndexedProperties.PrintServerLoggingProperty op_Implicit(PrintServerLoggingProperty)
System.Printing System.Printing.IndexedProperties.PrintDriverProperty op_Implicit(PrintDriverProperty)
System.Printing System.Printing.IndexedProperties.PrintPortProperty op_Implicit(PrintPortProperty)
System.Printing System.Printing.IndexedProperties.PrintServerProperty op_Implicit(PrintServerProperty)
System.Printing System.Printing.IndexedProperties.PrintTicketProperty op_Implicit(PrintTicketProperty)
System.Printing System.Printing.IndexedProperties.PrintByteArrayProperty op_Implicit(PrintByteArrayProperty)
System.Printing System.Printing.IndexedProperties.PrintProcessorProperty op_Implicit(PrintProcessorProperty)
System.Printing System.Printing.IndexedProperties.PrintQueueProperty op_Implicit(PrintQueueProperty)
System.Printing System.Printing.IndexedProperties.PrintJobPriorityProperty op_Implicit(PrintJobPriorityProperty)
System.Printing System.Printing.IndexedProperties.PrintJobStatusProperty op_Implicit(PrintJobStatusProperty)
System.Printing System.Printing.IndexedProperties.PrintDateTimeProperty op_Implicit(PrintDateTimeProperty)
System.Printing System.Printing.IndexedProperties.PrintSystemTypeProperty op_Implicit(PrintSystemTypeProperty)
System.Printing System.Windows.Xps.XpsDocumentWriter raise__WritingProgressChanged(Object,WritingProgressChangedEventArgs)
System.Printing System.Windows.Xps.XpsDocumentWriter raise__WritingCompleted(Object,WritingCompletedEventArgs)
System.Printing System.Windows.Xps.XpsDocumentWriter raise__WritingCancelled(Object,WritingCancelledEventArgs)
System.Drawing System.Drawing.FontConverter Finalize()

Portability to .NET Core 3.0 analysis

Microsoft offers a Portability Analyzer tool to analyze changes in desktop API that will break your desktop app. I’ve tested it on NDepend but I just got very coarse results. Did I miss something? At least it is mostly green 🙂

Portability Analyzer analysis on NDepend

I wrote last year a post named Quickly assess your .NET code compliance with .NET Standard let me know in comment if it is worth revisiting this post for desktop APIs. Btw, my guess is that desktop APIs won’t be part of .NET Standard vNext (since there is no plan to support it on all platforms) but I haven’t found any related info on the web.

Why migrate your desktop app to .NET Core 3.0?

This is a great news that Microsoft embeds good-old desktop APIs in .NET Core 3.0 with such an outstanding compatibility. It is worth noting that so far (February 2019) there is no plan to port Windows Forms and WPF on other platforms than Windows.  So, what are the benefits of porting an existing application to .NET Core 3.0?

I found answers in this recent How to Port Desktop Applications to .NET Core 3.0 Channel9 30 minutes video at 5:12. Basically you’ll get more deployment flexibility, Core Runtime and API improvements and also more performances.

Microsoft promises to not urge anyone to port existing Winforms and WPF application to .NET Core 3.0. However for a Visual Studio extension shop like us if it is decided that VS will run on .NET Core 3.0 in the future, we hope to be notified many months ahead. We discussed that on twitter with Amanda Silver in January 2019. It looks like this spring 2019 they will take a decision. As a consequence to support both Visual Studio past versions running on .NET fx and new versions running on .NET Core 3, an extension will need to support both .NET Fx and .NET Core 3 desktop APIs.

New .NET Core 2.1 and ASP.NET Core 2.1 APIs

.NET Core 2.1 and ASP.NET Core 2.1 Preview1 have just been released (see here the official announcement) and we are going to explore new APIs in this post. We’ll found out many of the new features announced in the .NET Core 2.1 Roadmap and ASP.NET Core 2.1 Roadmap on the MSDN blog.

We just released NDepend v2018.1 and we took a chance to support analysis of .NET Core 2.1 and ASP.NET Core 2.1 applications. NDepend is often deemed as the Swiss-Army Knife for .NET developers thanks to its code query language (CQLinq). CQLinq can be used to write code rules, quality gatestrend code metrics, explore dependencies or advanced code search. One thing CQLinq excels at is exploring the diff between two snapshots of a code base. Exploring new APIs is a sub-task of exploring what was changed. Let’s harness this capability to explore new .NET Core 2.1 APIs.

New .NET Core 2.1 Preview1 APIs

We could have downloaded sources files of both .NET Core 2.1.0 Preview1 and 2.0.0, recompile and then do the diff. Instead, since NDepend can analyze raw assemblies even without sources available, we compared assemblies in these two folders:

  • C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.1.0-preview1-26216-03
  • C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.5

Here is the CQLinq code query that lists all new public classes and types. It is also refined to match public members (methods and fields) of each new type in the result.

Find the whole list here .NET Core 2.1 new public classes. Here is a first glimpse in the screenshot below. We highlighted the new great Span<T> capability.

.NET Core 2.1 new classes

Not only new public classes list is interesting, but also new public methods added on existing public classes. This query does list these 1.500 methods:

Here also find a screenshot below and the whole list here: .NET Core 2.1 new public methods on existing public classes. For this screenshot we used the new Dark theme support of NDepend v2018.1.

.NET Core 2.1 new public methods

Interestingly enough let’s list new namespaces that contain at least one public type:

.NET Core 2.1 new public namespaces

 

New ASP.NET Core 2.1 Preview1 APIs

To analyze ASP.NET Core assemblies it was a bit more difficult than just comparing assemblies in 2 folders. ASP.NET Core assemblies are stored in NuGet packages so we did explore assemblies in the folder C:\Program Files\dotnet\sdk\NuGetFallbackFolder and then tinker a bit to get the wanted versions in both 2.1 and 2.0 cases.

Let’s use the same code query to match ASP.NET Core 2.1 new public classes :

ASP.NET Core 2.1 new public class

The same way here is the ASP.NET Core 2.1 new public methods on existing public classes :

ASP.NET Core 2.1 new public methods in existing public classes

And finally, here are the new ASP.NET Core 2.1 namespaces that contain at least one public classes.

ASP.NET Core 2.1 new namespaces

 

 

Static analysis of .NET Core 2.0 applications

NDepend v2017.3 has just been released with major improvements. One of the most requested features, now available, is the support for analyzing .NET Core 2.0 and .NET Standard 2.0 projects. .NET Core and its main flavor, ASP.NET Core, represents a major evolution for the .NET platform. Let’s have a look at how NDepend is analyzing .NET Core code.

Resolving .NET Core third party assemblies

In this post I’ll analyze the OSS application ASP.NET Core / EntityFramework MusicStore hosted on github. From the Visual Studio solution file, NDepend is resolving the application assembly MusicStore.dll and also two test assemblies that we won’t analyze here. In the screenshot below, we can see that:

  • NDepend recognizes the .NET profile, .NET Core 2.0, for this application.
  • It resolves several folders on the machine that are related to .NET Core, especially NuGet package folders.
  • It resolves all 77 third-party assemblies referenced by MusicStore.dll. This is important since many code rules and other NDepend features take into account what the application code is using.

It is worth noticing that the .NET Core platform assemblies have high granularity. A simple website like MusicStore references no fewer than 77 assemblies. This is because the .NET Core framework is implemented through a few NuGet packages that each contain many assemblies. The idea is to release the application only with needed assemblies, in order to reduce the memory footprint.

.NET Core 2.0 third party assemblies granularity

NDepend v2017.3 has a new heuristic to resolve .NET Core assemblies. This heuristic is based on .deps.json files that contain the names of the NuGet packages referenced. Here we can see that 3 NuGet packages are referenced by MusicStore. From these package names, the heuristic will resolve third-party assemblies (in the NuGet store) referenced by the application assemblies (MusicStore.dll in our case).

NuGet packages referenced in .deps.json file

Analyzing .NET Standard assemblies

Let’s be clear that NDepend v2017.3 can also analyze .NET Standard assemblies. Interestingly enough, since .NET Standard 2.0, .NET Standard assemblies reference a unique assembly named netstandard.dll and found in C:\Users\[user]\.nuget\packages\NETStandard.Library\2.0.0\build\netstandard2.0\ref\netstandard.dll.

By decompiling this assembly, we can see that it doesn’t contain any implementation, but it does contain all types that are part of .NET Standard 2.0. This makes sense if we remember that .NET Standard is not an implementation, but is a set of APIs implemented by various .NET profiles, including .NET Core 2.0, the .NET Framework v4.6.1, Mono 5.4 and more.

Browsing how the application is using .NET Core

Let’s come back to the MusicStore application that references 77 assemblies. This assembly granularity makes it impractical to browse dependencies with the dependency graph, since this generates dozens of items. We can see that NDepend suggests viewing this graph as a dependency matrix instead.

NDepend Dependency Graph on an ASP.NET Core 2.0 project

The NDepend dependency matrix can scale seamlessly on a large number of items. The numbers in the cells also provide a good hint about the represented coupling. For example, here we can see that  22 members of the assembly Microsoft.EntityFrameworkCore.dll are used by 32 methods of the assembly MusicStore.dll, and a menu lets us dig into this coupling.

NDepend Dependency Matrix on an ASP.NET Core 2.0 project

Clicking the menu item Open this dependency shows a new dependency matrix where only members involved are kept (the 32 elements in column are using the 22 elements in rows). This way you can easily dig into which part of the application is using what.

NDepend Dependency Matrix on an ASP.NET Core 2.0 project

All NDepend features now work when analyzing .NET Core

We saw how to browse the structure of a .NET Core application, but let’s underline that all NDepend features now work when analyzing .NET Core applications. On the Dashboard we can see code quality metrics related to Quality Gates, Code Rules, Issues and Technical Debt.

NDepend Dashboard on an ASP.NET Core 2.0 project

Also, most of the default code rules have been improved to avoid reporting false positives on .NET Core projects.

NDepend code rules on an ASP.NET Core 2.0 project

We hope you’ll enjoy using all your favorite NDepend features on your .NET Core projects!