C# SimpleInjector强制生活方式。对于未注册类型为瞬态
我有一个包装器类,如下所示:C# SimpleInjector强制生活方式。对于未注册类型为瞬态,c#,inversion-of-control,simple-injector,C#,Inversion Of Control,Simple Injector,我有一个包装器类,如下所示: // this is not used for IoC purposes, but by code to cast object to known T internal interface ITaskCompletionSourceWrapper { void SetResult(object result); /* snip */ } internal class TaskCompletionSourceGenericWrapper<TRe
// this is not used for IoC purposes, but by code to cast object to known T
internal interface ITaskCompletionSourceWrapper
{
void SetResult(object result);
/* snip */
}
internal class TaskCompletionSourceGenericWrapper<TResult> : ITaskCompletionSourceWrapper
{
readonly TaskCompletionSource<TResult> tcs;
public TaskCompletionSourceGenericWrapper() =>
this.tcs = new TaskCompletionSource<TResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void SetResult(object result) => tcs.SetResult((TResult)result);
/* snip */
}
//这不是用于IoC目的,而是由代码将对象强制转换为已知的T
内部接口ITaskCompletionSourceWrapper
{
无效设置结果(对象结果);
/*剪断*/
}
内部类TaskCompletionSourceGenericWrapper:ITaskCompletionSourceWrapper
{
只读任务完成源tcs;
public TaskCompletionSourceGenericWrapper()=>
this.tcs=新TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
public void SetResult(object result)=>tcs.SetResult((TResult)result);
/*剪断*/
}
我当前使用Activator实例化的位置:
var responseType = request
.GetType()
.GetInterfaces()
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRequest<>))
GetGenericArguments()[0];
var wrapperType = typeof(TaskCompletionSourceGenericWrapper<>).MakeGenericType(responseType);
var tcsWrapper = this.container.GetInstance(wrapperType) as ITaskCompletionSourceWrapper;
var responseType=请求
.GetType()
.GetInterfaces()
.FirstOrDefault(i=>i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(IRequest))
GetGenericArguments()[0];
var wrapperType=typeof(TaskCompletionSourceGenericWrapper);
var tcswapper=this.container.GetInstance(wrapperType)作为ITaskCompletionSourceWrapper;
我将此切换到SimpleInjector(可能使用日志记录和其他IOC功能),并认为一切正常,直到我发现一个问题(这是由于生活方式被共享):
/*从上面剪下响应类型代码*/
var wrapperType=typeof(TaskCompletionSourceGenericWrapper);
var tcswapper=this.container.GetInstance(wrapperType)作为ITaskCompletionSourceWrapper;
//我可以看到类型已注册为作用域,但我们需要它是唯一的
[30]=ServiceType=TaskCompletionSourceGenericWrapper,Lifestyle=Async作用域
在AsyncScopedLifestyle.BeginScope
块中调用上述函数
我想在运行时使用SimpleInjector实例化这个包装器(但要确保lifesture.Transient
):
包装器的类型在int
、string
、bool
等中几乎是任意的,但也可以是简单的POCO类
这类似于开放泛型注册的情况,但我宁愿避免让其他开发人员为简单类型指定程序集(因为他们肯定会忘记,而且他们的类无论如何都很简单—命令/查询POCOs等等)
我怎样才能达到上述要求,或者我是被迫注册收款的
或者这是生活方式不匹配造成的更深层次的问题——我希望不是,因为包装器没有依赖项(可能除了ILogger之外也不会),只是在对一个简单类进行实例化(我想替换Activator,而不是按照IoC风格解耦组件)。基于他们的文档和经验,使用依赖项注入时,需要注册接口的实现
var container = new Container();
// If related classes exist in a different assembly then add them here
var assemblies = new[] { typeof(TaskCompletionSourceGenericWrapper<>).Assembly };
container.Collection.Register(typeof(TaskCompletionSourceGenericWrapper<>), assemblies, Lifestyle.Transient);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
var container = new Container();
// If related classes exist in a different assembly then add them here
var assemblies = new[] { typeof(TaskCompletionSourceGenericWrapper<>).Assembly };
container.Collection.Register(typeof(TaskCompletionSourceGenericWrapper<>), assemblies, Lifestyle.Transient);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
public interface IUglyDuckling
{
ITaskCompletionSourceWrapper GetITaskCompletionSourceWrapper(Type type);
}
public class UglyDuckling : IUglyDuckling
{
public ITaskCompletionSourceWrapper GetITaskCompletionSourceWrapper(Type type)
{
var wrapperType = typeof(TaskCompletionSourceGenericWrapper<>).MakeGenericType(type);
var tcsWrapper = this.container.GetInstance(wrapperType) as ITaskCompletionSourceWrapper;
return ObjectCopier.Clone<ITaskCompletionSourceWrapper>(tcsWrapper);
}
}