FiberModule.cs
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license.
4 //
5 // Microsoft Bot Framework: http://botframework.com
6 //
7 // Bot Builder SDK GitHub:
8 // https://github.com/Microsoft/BotBuilder
9 //
10 // Copyright (c) Microsoft Corporation
11 // All rights reserved.
12 //
13 // MIT License:
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 
34 using System;
35 using System.Collections.Generic;
36 using System.Diagnostics;
37 using System.IO;
38 using System.Linq;
39 using System.Runtime.Serialization;
40 using System.Runtime.Serialization.Formatters.Binary;
41 
42 using Autofac;
43 using Autofac.Core;
44 
46 
47 namespace Microsoft.Bot.Builder.Internals.Fibers
48 {
52  public abstract class FiberModule : Module
53  {
54  public static readonly object Key_DoNotSerialize = new object();
55  public static readonly object Key_SurrogateProvider = new object();
56 
63  private static IEnumerable<object> DoNotSerialize(IComponentContext context, IEnumerable<Parameter> parameters)
64  {
65  foreach (var registration in context.ComponentRegistry.Registrations)
66  {
67  foreach (var service in registration.Services)
68  {
69  var keyed = service as KeyedService;
70  if (keyed != null)
71  {
72  if (keyed.ServiceKey == Key_DoNotSerialize)
73  {
74  object instance;
75  if (context.TryResolveService(service, parameters, out instance))
76  {
77  yield return instance;
78  }
79  }
80  }
81  }
82  }
83  }
84 
85  protected override void Load(ContainerBuilder builder)
86  {
87  base.Load(builder);
88 
89  // singleton components
90 
91  builder
92  .RegisterType<DefaultTraceListener>()
93  .As<TraceListener>()
94  .SingleInstance();
95 
96  builder
97  .Register(c => Comparer<double>.Default)
98  .As<IComparer<double>>();
99 
100  builder
101  .Register(c => NormalizedTraits.Instance)
102  .As<ITraits<double>>()
103  .SingleInstance();
104 
105  builder
106  .Register(c => new Serialization.StoreInstanceByTypeSurrogate(priority: int.MaxValue))
107  .Keyed<Serialization.ISurrogateProvider>(Key_SurrogateProvider)
108  .SingleInstance();
109 
110  builder
111  .Register(c => new Serialization.ClosureCaptureErrorSurrogate(priority: 1))
112  .Keyed<Serialization.ISurrogateProvider>(Key_SurrogateProvider)
113  .SingleInstance();
114 
115  builder
116  .Register(c => new Serialization.JObjectSurrogate(priority: 3))
117  .Keyed<Serialization.ISurrogateProvider>(Key_SurrogateProvider)
118  .SingleInstance();
119 
120  builder
121  .RegisterDecorator<Serialization.ISurrogateProvider>((c, inner) => new Serialization.SurrogateLogDecorator(inner, c.Resolve<TraceListener>()), fromKey: Key_SurrogateProvider);
122 
123  builder
124  .RegisterType<Serialization.SurrogateSelector>()
125  .As<ISurrogateSelector>()
126  .SingleInstance();
127 
128  // per request, depends on resolution parameters through "p"
129 
130  builder
131  .Register((c, p) => new ArrayResolver(NullResolver.Instance, DoNotSerialize(c, p).Distinct().ToArray()))
132  .As<IResolver>()
133  .InstancePerLifetimeScope();
134 
135  builder
136  .Register((c, p) => new BinaryFormatter(c.Resolve<ISurrogateSelector>(), new StreamingContext(StreamingContextStates.All, c.Resolve<IResolver>(p))))
137  .As<IFormatter>()
138  .InstancePerLifetimeScope();
139  }
140  }
141 
145  public sealed class FiberModule<C> : FiberModule
146  {
147  protected override void Load(ContainerBuilder builder)
148  {
149  base.Load(builder);
150 
151  // [Serializable] components, serialized as type, deserialized through container resolution of type
152 
153  builder
154  .RegisterType<WaitFactory<C>>()
155  .Keyed<IWaitFactory<C>>(Key_DoNotSerialize)
156  .As<IWaitFactory<C>>()
157  .SingleInstance();
158 
159  builder
160  .RegisterType<FrameFactory<C>>()
161  .Keyed<IFrameFactory<C>>(Key_DoNotSerialize)
162  .As<IFrameFactory<C>>()
163  .SingleInstance();
164 
165  builder
166  .RegisterInstance(NullWait<C>.Instance)
167  .Keyed<NullWait<C>>(Key_DoNotSerialize)
168  .AsSelf()
169  .SingleInstance();
170 
171  // per request, no resolution parameter dependency
172 
173  builder
174  .RegisterType<Fiber<C>>()
175  .As<IFiberLoop<C>>()
176  .InstancePerDependency();
177 
178  builder
179  .Register((c, p) => new FactoryStore<IFiberLoop<C>>(new ErrorResilientStore<IFiberLoop<C>>(new FormatterStore<IFiberLoop<C>>(p.TypedAs<Stream>(), c.Resolve<IFormatter>(p))), c.Resolve<Func<IFiberLoop<C>>>(p)))
180  .As<IStore<IFiberLoop<C>>>()
181  .InstancePerDependency();
182 
183  builder
184  .RegisterType<StoreFromStack<C>>()
185  .AsImplementedInterfaces()
186  .InstancePerLifetimeScope();
187  }
188  }
189 
190  public sealed class ReflectionSurrogateModule : Module
191  {
192  protected override void Load(ContainerBuilder builder)
193  {
194  base.Load(builder);
195 
196  builder
197  .Register(c => new Serialization.StoreInstanceByFieldsSurrogate(priority: 2))
198  .Keyed<Serialization.ISurrogateProvider>(FiberModule.Key_SurrogateProvider)
199  .SingleInstance();
200  }
201  }
202 }
Autofac module for Fiber components.
Definition: FiberModule.cs:52
static readonly ITraits< double > Instance
Definition: Traits.cs:50
Extend ISerializationSurrogate with a "tester" method used by SurrogateSelector.
Allow the resolution of values based on type and optionally tag.
Namespace for internal scorable implementation that is not useful for most developers and may change ...
Namespace for scorable interfaces, classes and compositions.
override void Load(ContainerBuilder builder)
Definition: FiberModule.cs:85
Null object pattern implementation of wait interface.
Definition: Wait.cs:127
Root namespace for the Microsoft Bot Builder SDK.