asp.net使用StructureMap等依赖注入组件时最重要就是EntityFramework的DbContext对象要保证在每次HttPRequest只有一个DbContext实例,这里将使用第三方提供的HttpSimulator进行测试。
创建屏蔽不同依赖注入组件使用差别的接口。
public interface IDependency{ void Build(); void EndRequest(); void AddTransient(Type from, Type to, object instance = null); void AddScoped(Type from, Type to, object instance = null); void AddSingleton(Type from, Type to, object instance = null); object GetInstance(Type type); IEnumerable GetAllInstances(Type type);}
public class StructureMapAdapter : IDependency, IDisposable{ private bool _disposed = false; private Container _container; private Registry _registry; public StructureMapAdapter() { this._registry = new Registry(); } public void Build() { _container = new Container(_registry); } public void EndRequest() { HttpContextLifecycle.DisposeAndClearAll(); } public void AddTransient(Type from, Type to, object instance = null) { if (instance == null) { _registry.For(from).Use(to).LifecycleIs<TransientLifecycle>(); } else { _registry.For(from).Use(instance).LifecycleIs<TransientLifecycle>(); } } public void AddScoped(Type from, Type to, object instance = null) { if (instance == null) { _registry.For(from).Use(to).LifecycleIs<HttpContextLifecycle>(); } else { _registry.For(from).Use(instance).LifecycleIs<HttpContextLifecycle>(); } } public void AddSingleton(Type from, Type to, object instance = null) { if (instance == null) { _registry.For(from).Use(to).LifecycleIs<SingletonLifecycle>(); } else { _registry.For(from).Use(instance).LifecycleIs<SingletonLifecycle>(); } } public object GetInstance(Type type) { return _container.GetInstance(type); } public IEnumerable GetAllInstances(Type type) { return _container.GetAllInstances(type); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { this._container.Dispose(); } _disposed = true; } }}
public class StructureMapAdapterTest{ [Fact] public void TransientTest() { IDependency dependency = new StructureMapAdapter(); dependency.AddTransient(typeof(ITest), typeof(Test)); dependency.Build(); var version1 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; var version2 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; Assert.NotEqual(version1, version2); } [Fact] public void SingletonTest() { IDependency dependency = new StructureMapAdapter(); dependency.AddSingleton(typeof(ITest), typeof(Test)); dependency.Build(); var version1 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; var version2 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; Assert.Equal(version1, version2); } [Fact] public void ScopedTest() { var version1 = ""; var version2 = ""; using (HttpSimulator simulator = new HttpSimulator()) { IDependency dependency = new StructureMapAdapter(); dependency.AddScoped(typeof(ITest), typeof(Test)); dependency.Build(); simulator.SimulateRequest(new Uri("http://localhost/")); version1 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; version2 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; Assert.Equal(version1, version2); } using (HttpSimulator simulator = new HttpSimulator()) { IDependency dependency = new StructureMapAdapter(); dependency.AddScoped(typeof(ITest), typeof(Test)); dependency.Build(); simulator.SimulateRequest(new Uri("http://localhost/")); version1 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; } using (HttpSimulator simulator = new HttpSimulator()) { IDependency dependency = new StructureMapAdapter(); dependency.AddScoped(typeof(ITest), typeof(Test)); dependency.Build(); simulator.SimulateRequest(new Uri("http://localhost/")); version2 = ((ITest)dependency.GetInstance(typeof(ITest))).Version; } Assert.NotEqual(version1, version2); }}public interface ITest{ String Version { get; }}public class Test : ITest{ private string _version = Guid.NewGuid().ToString(); public string Version { get { return this._version; } }}
运行结果:
新闻热点
疑难解答