您对以下内容的理解文档 http://structuremap.github.io/object-lifecycle/supported-lifecycles/是不正确的。
- 瞬态——默认生命周期。为每个逻辑请求创建一个新对象,以解析容器中的对象图。
- Singleton——只会为该容器以及该容器创建的任何子容器或嵌套容器创建一个对象实例
您正在使用短暂的,这意味着你得到一个实例每次Resolve
叫做.
但你所描述的行为是为了辛格尔顿,这意味着创建实例只是第一次Resolve
叫做.
要获得您想要的行为,您必须将注册类型更改为辛格尔顿.
public class ConsoleRegistry : Registry
{
public ConsoleRegistry()
{
Scan(_ =>
{
_.TheCallingAssembly();
_.With(new SingletonConvention<IFileService>());
_.WithDefaultConventions();
});
}
}
internal class SingletonConvention<TPluginFamily> : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsConcrete() || !type.CanBeCreated() || !type.AllInterfaces().Contains(typeof(TPluginFamily))) return;
registry.For(typeof(TPluginFamily)).Singleton().Use(type);
}
}
参考:如何将 Structuremap 配置为通过 Singleton 自动扫描 Assembly 和 Cache 中的类型? https://stackoverflow.com/q/977862
单例 VS 瞬态示例
思考这个问题最简单的方法是举一个例子without使用 DI 容器。
Services
这里我们有一个服务和一个应用服务。这里唯一真正的区别是应用程序服务旨在整个应用图.
public class Service
{
public string Name { get; private set; } = Guid.NewGuid().ToString();
}
public class Application
{
private readonly Service singleton;
private readonly Service transient;
public Application(Service singleton, Service transient)
{
this.singleton = singleton;
this.transient = transient;
}
public Service Singleton { get { return singleton; } }
public Service Transient { get { return transient; } }
}
容器
在我们的容器中,我们注册了 2 个实例Service
,一个单例和一个瞬态。单例仅被实例化每个容器实例一次。瞬态被实例化每次Resolve
叫做.
public class MyContainer
{
private readonly Service singleton = new Service();
public Application Resolve()
{
return new Application(
singleton: this.singleton,
transient: new Service());
}
}
Usage
在现实世界的应用程序中,只会有一个实例Application
。然而,我们展示的是两个Application
实例来证明服务注册为Singleton
将是同一容器实例的同一实例。每次都会创建一个瞬态Resolve
叫做。
class Program
{
static void Main(string[] args)
{
var container = new MyContainer();
var application1 = container.Resolve();
var application2 = container.Resolve();
Console.WriteLine($"application1.Transient.Name: {application1.Transient.Name}");
Console.WriteLine($"application2.Transient.Name: {application2.Transient.Name}");
Console.WriteLine();
Console.WriteLine($"application1.Singleton.Name: {application1.Singleton.Name}");
Console.WriteLine($"application2.Singleton.Name: {application2.Singleton.Name}");
Console.ReadKey();
}
}
Output
application1.Transient.Name:dc134d4d-75c8-4f6a-a1a5-367156506671
application2.Transient.Name:f3012ea2-4955-4cfa-8257-8e03a00b1e99
application1.Singleton.Name:86d06d7d-a611-4f57-be98-036464797a41
application2.Singleton.Name:86d06d7d-a611-4f57-be98-036464797a41