栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

【DryIOC】瞬态服务(Reuse.Transient Service)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【DryIOC】瞬态服务(Reuse.Transient Service)

DryIOC支持多种状态的Service,瞬态服务(Reuse.Transient Service)仅是其中一种。意味着该服务不会被重用。调用Resove方法或者注入时,都会重新创建一个服务实例。当你在注册服务时省略reuse参数或者没有改变容器的 Container.Rules.DefaultReuse属性,瞬态服务是容器的默认状态。

container.Register(Reuse.Transient);
container.Register();
1. 实现IDisposable接口的瞬态服务

当您注册的服务实现了IDispoable接口,该瞬态服务的释放职责将编程一个问题。这需要分成两种情况进行讨论。

1.1 通过Resolve方法获取瞬态服务实例

注意
DryIOC默认情况下不支持实现IDispoable接口的瞬态服务的注册。可通过以下两种方式就行配置以实现支持:

  • 在调用注册函数时,设置allowDisposableTransient: true。这种方式仅影响当前注册的服务
  • 在创建容器时使用Rules.WithoutThrowonRegisteringDisposableTransient() 修改容器规则。这种方式是全局的

产生问题的原因
如果允许注册实现了IDisposable接口的服务,那么需要开发者自行管理创建的瞬态服务实例的释放工作。

// 定义容器变量
Container container;
// 指示是否通过全局方式允许容器支持实现`IDisposable`接口的瞬态服务
bool isUseGlobelFlag = false;

void Main()
{
	System.Console.WriteLine("容器创建");
	if (isUseGlobelFlag)
		container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient());
	else
		container = new Container();
	
	// 执行方法
	DisposableTransientService();
	
	System.Console.WriteLine("容器释放");
	container.Dispose();
	
	System.Console.WriteLine("程序结束");
}


void DisposableTransientService()
{
	System.Console.WriteLine("服务注册");
	if (isUseGlobelFlag)
		container.Register();
	else
		container.Register(setup:Setup.With(allowDisposableTransient:true));
	
	System.Console.WriteLine("服务解析");

	var x = container.Resolve();
	x.Dispose();
}

class X : System.IDisposable
{
	public X()
	{
		System.Console.WriteLine(nameof(X) + " is created.");
	}

	public void Dispose()
	{
		System.Console.WriteLine(nameof(X) + " is disposed.");
	}
}

容器创建
服务注册
服务解析
X is created.
X is disposed.
容器释放
程序结束

上述程序的运行结果不会出现任何问题,因为我们可以手动的对瞬态服务的实例进行释放。如果注释掉DisposableTransientService方法种的x.Dispose();语句,运行后可以发现,x的释放工作将不被执行。这也从侧面验证了当允许容器注册实现了IDispoable接口的瞬态服务,瞬态服务实例的释放将不被执行。

容器创建
服务注册
服务解析
X is created.
容器释放
程序结束

1.2 通过注入的方式获取瞬态服务实例
// 定义容器变量
Container container;
// 指示是否通过全局方式允许容器支持实现`IDisposable`接口的瞬态服务
bool isUseGlobelFlag = false;

void Main()
{
	System.Console.WriteLine("容器创建");
	if (isUseGlobelFlag)
		container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient());
	else
		container = new Container();
	
	// 执行方法
	DisposableTransientService();
	
	System.Console.WriteLine("容器释放");
	container.Dispose();
	
	System.Console.WriteLine("程序结束");
}


void DisposableTransientService()
{
	System.Console.WriteLine("服务注册");
	if (isUseGlobelFlag)
		container.Register();
	else
		container.Register(setup:Setup.With(allowDisposableTransient:true));		
	container.Register();
	
	System.Console.WriteLine("服务解析");

	var user = container.Resolve();
}

class X : System.IDisposable
{
	public X()
	{
		System.Console.WriteLine(nameof(X) + " is created.");
	}

	public void Dispose()
	{
		System.Console.WriteLine(nameof(X) + " is disposed.");
	}
}

class XUser
{
	public XUser(X x)
	{
		System.Console.WriteLine(nameof(XUser) + " is created.");
	}
}

容器创建
服务注册
服务解析
X is created.
XUser is created.
容器释放
程序结束

这里实现IDisposable接口的瞬态服务被作为XUser类构造函数的一个依赖。这种情况下,我们无法获得X类型的注入实例,也就无法手动进行释放。从而导致释放的问题。

2. 实现IDisposable接口的瞬态服务的跟踪

为了解决上述问题,DryIOC提供了一种机制对注入的瞬态服务进行跟踪,以便在适当的时候进行释放。

// 定义容器变量
Container container;
// 指示是否通过全局方式跟踪实现`IDisposable`接口的瞬态服务
bool isUseGlobelTrack = false;

void Main()
{
	System.Console.WriteLine("容器创建");
	if (isUseGlobelTrack)
		container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient().WithTrackingDisposableTransients());
	else
		container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient());
	
	// 执行方法
	DisposableTransientService();
	
	System.Console.WriteLine("容器释放");
	container.Dispose();
	
	System.Console.WriteLine("程序结束");
}


void DisposableTransientService()
{
	System.Console.WriteLine("服务注册");
	if (isUseGlobelTrack)
		container.Register();
	else
		container.Register(setup:Setup.With(trackDisposableTransient:true));		
	container.Register();
	
	System.Console.WriteLine("服务解析");

	var user = container.Resolve();
}

class X : System.IDisposable
{
	public X()
	{
		System.Console.WriteLine(nameof(X) + " is created.");
	}

	public void Dispose()
	{
		System.Console.WriteLine(nameof(X) + " is disposed.");
	}
}

class XUser
{
	public XUser(X x)
	{
		System.Console.WriteLine(nameof(XUser) + " is created.");
	}
}

容器创建
服务注册
服务解析
X is created.
XUser is created.
容器释放
X is disposed.
程序结束

由结果可以看出,瞬态服务释放的问题得到解决。

3. 阻止瞬态服务的跟踪 3.1 方式一:指定preventDisposal=true
// 定义容器变量
Container container;

void Main()
{
	System.Console.WriteLine("容器创建");
	container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient().WithTrackingDisposableTransients());
	
	// 执行方法
	DisposableTransientService();
	
	System.Console.WriteLine("容器释放");
	container.Dispose();
	
	System.Console.WriteLine("程序结束");
}


void DisposableTransientService()
{
	System.Console.WriteLine("服务注册");
	container.Register(setup:Setup.With(preventDisposal:true));
	container.Register();
	
	System.Console.WriteLine("服务解析");

	var user = container.Resolve();
}

class X : System.IDisposable
{
	public X()
	{
		System.Console.WriteLine(nameof(X) + " is created.");
	}

	public void Dispose()
	{
		System.Console.WriteLine(nameof(X) + " is disposed.");
	}
}

class XUser
{
	public XUser(X x)
	{
		System.Console.WriteLine(nameof(XUser) + " is created.");
	}
}

容器创建
服务注册
服务解析
X is created.
XUser is created.
容器释放
程序结束

3.2 方式二:使用Func
// 定义容器变量
Container container;
XFactory xf;
static X xGlobal;
void Main()
{
	System.Console.WriteLine("容器创建");
	container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient().WithTrackingDisposableTransients());
	
	// 执行方法
	DisposableTransientService();
	
	System.Console.WriteLine("容器释放");
	container.Dispose();
	
	// 获取时创建一个心的X
	var xx = xf.GetX();
	Console.WriteLine(xx == xf.X);
	System.Console.WriteLine("程序结束");
}


void DisposableTransientService()
{
	System.Console.WriteLine("服务注册");
	container.Register();
	container.Register();
	
	System.Console.WriteLine("服务解析");

	Console.WriteLine("=========================");
	xf = container.Resolve();
}

class X : System.IDisposable
{
	public X()
	{
		System.Console.WriteLine(nameof(X) + " is created.");
	}

	public void Dispose()
	{
		System.Console.WriteLine(nameof(X) + " is disposed.");
	}
}

class XFactory
{
	public readonly Func GetX;
	public readonly X X;
	
	// 注入x时创建一个X
	public XFactory(Func getX, X x)
	{
		Console.WriteLine("=========================");
		xGlobal = x;
		this.X = x;
		this.GetX = getX;
		System.Console.WriteLine(nameof(XFactory) + " is created.");
	}
}

容器创建
服务注册
服务解析
=========================
X is created.
=========================
XFactory is created.
容器释放
X is disposed.
X is created.
False
程序结束

在构造XFactory时通过构造函数的参数x完成了一次注入,此时创建了一个X的实例。该实例在容器给释放时被释放。指定var xx = xf.GetX();语句时重新创建了一个X的实例。两次创建的实例不相同。

4. 使用其他默认reuse代替瞬态服务
void Main()
{
	var container = new Container(rules => rules.WithDefaultReuse(Reuse.Scoped));

	container.Register();

	using (var scope = container.OpenScope())
	{
		var abc = scope.Resolve();
		Console.WriteLine(abc == scope.Resolve());
	}
}

class Abc { }

True

在同一个Scope中创建的实例是相同的.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/603604.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号