1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Collections.Generic;
7 using System.Composition;
8 using System.Composition.Hosting;
9 using System.Diagnostics;
10 using System.Linq;
11 using System.Text;
12 using System.Threading;
13 using System.Threading.Tasks;
14 
15 namespace CompositionThroughput
16 {
17     internal abstract class WebBenchmark : Benchmark
18     {
GetOperation()19         public override Action GetOperation()
20         {
21             var op = GetCompositionOperation();
22             return () => op().Item2();
23         }
24 
SelfTest()25         public override bool SelfTest()
26         {
27             var op = GetCompositionOperation();
28             var r1 = op();
29 
30             if (!(r1.Item1 is Web.OperationRoot))
31                 return false;
32 
33             r1.Item2();
34             var or1 = (Web.OperationRoot)r1.Item1;
35             if (!(or1.Long.TailA.IsDisposed &&
36                 or1.Long.TailA.TailB.IsDisposed &&
37                 or1.Long.TailA.TailB.TailC.IsDisposed))
38                 return false;
39 
40             if (or1.Wide.A1 != or1.Wide.A2)
41                 return false;
42 
43             var r2 = op();
44             if (r2.Item1 == r1.Item1)
45                 return false;
46 
47             var or2 = (Web.OperationRoot)r2.Item1;
48             if (or2.Long.TailA.IsDisposed)
49                 return false;
50 
51             if (or1.Wide.A1 == or2.Wide.A1)
52                 return false;
53 
54             if (or1.Wide.A1.GA != or2.Wide.A1.GA)
55                 return false;
56 
57             r2.Item2();
58             return true;
59         }
60 
GetCompositionOperation()61         public abstract Func<Tuple<object, Action>> GetCompositionOperation();
62     }
63 
64     internal class LightweightWebBenchmark : WebBenchmark
65     {
66         [Export]
67         private class WebServer
68         {
69 #pragma warning disable 3016
70             [Import, SharingBoundary(Web.Boundaries.Web)]
71 #pragma warning restore 3016
72             public ExportFactory<Web.OperationRoot> WebScopeFactory { get; set; }
73         }
74 
GetCompositionOperation()75         public override Func<Tuple<object, Action>> GetCompositionOperation()
76         {
77             var container = new ContainerConfiguration()
78                 .WithParts(new[]{
79                     typeof(WebServer),
80                     typeof(Web.OperationRoot),
81                     typeof(Web.GlobalA),
82                     typeof(Web.GlobalB),
83                     typeof(Web.Transient),
84                     typeof(Web.Wide),
85                     typeof(Web.A),
86                     typeof(Web.B),
87                     typeof(Web.Long),
88                     typeof(Web.TailA),
89                     typeof(Web.TailB),
90                     typeof(Web.TailC)})
91                 .CreateContainer();
92 
93             var sf = container.GetExport<WebServer>().WebScopeFactory;
94             return () =>
95             {
96                 var x = sf.CreateExport();
97                 return Tuple.Create<object, Action>(x.Value, x.Dispose);
98             };
99         }
100     }
101 
102     internal class NativeCodeWebBenchmark : WebBenchmark
103     {
GetCompositionOperation()104         public override Func<Tuple<object, Action>> GetCompositionOperation()
105         {
106             var globalA = new Web.GlobalA();
107             var globalB = new Web.GlobalB();
108             return () =>
109             {
110                 var tc = new Web.TailC();
111                 var tb = new Web.TailB(tc);
112                 var ta = new Web.TailA(tb);
113                 var a = new Web.A(globalA);
114                 var b = new Web.B(globalB);
115                 var transient = new Web.Transient();
116                 var w = new Web.Wide(a, a, b, transient);
117                 var l = new Web.Long(ta);
118                 var r = new Web.OperationRoot(w, l);
119                 return Tuple.Create<object, Action>(r, () => { ta.Dispose(); tb.Dispose(); tc.Dispose(); });
120             };
121         }
122     }
123 
124     internal static class CompositionScope
125     {
126         public const string Global = "Global";
127     }
128 }
129