问问题
493 次
3 回答
1
此答案基于Nicholas 的评论和他在IRegistrationSource 上的博客文章
public class OwnedPerRequest<T> : Owned<T>
{
public OwnedPerRequest(T value, IDisposable lifetime) : base(value, lifetime) { }
}
public class OwnedPerRequestInstanceRegistrationSource : IRegistrationSource
{
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
if (service == null)
throw new ArgumentNullException(nameof(service));
if (registrationAccessor == null)
throw new ArgumentNullException(nameof(registrationAccessor));
var swt = service as IServiceWithType;
if (swt == null
|| !(swt.ServiceType.IsGenericType
&& swt.ServiceType.GetGenericTypeDefinition() == typeof(OwnedPerRequest<>)))
return Enumerable.Empty<IComponentRegistration>();
var ownedInstanceType = swt.ServiceType.GetGenericArguments()[0];
var ownedInstanceService = swt.ChangeType(ownedInstanceType);
return registrationAccessor(ownedInstanceService)
.Select(r =>
{
var rb = RegistrationBuilder.ForDelegate(swt.ServiceType, (c, p) =>
{
var lifetime = c.Resolve<ILifetimeScope>().BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
try
{
var value = lifetime.ResolveComponent(r, p);
return Activator.CreateInstance(swt.ServiceType, value, lifetime);
}
catch
{
lifetime.Dispose();
throw;
}
});
return rb
.ExternallyOwned()
.As(service)
.Targeting(r)
.CreateRegistration();
});
}
public bool IsAdapterForIndividualComponents => true;
public override string ToString() => "OwnedPerRequestInstanceregistrationSource";
}
于 2016-12-15T11:56:08.977 回答
0
我认为你想要做的是注入Func<Owned<B>>
你在需要 B 时调用的 a。这将删除服务定位器模式,我很确定在功能上与 this 相同
using (var scope = this.lifetimeScope.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
{
var b = scope.Resolve<B>();
b.DoSomething();
}
如果您注入 a Func<Owned<B>>
,用法将如下所示:
public void DoSomethingThatUsesB()
{
//_bFactory is your Func<Owned<B>>
using(var b = _bFactory.Invoke())
{
... (use b)
}
}
于 2016-08-24T19:45:46.317 回答
0
如果您的应用程序的生命周期结构非常简单(即您没有在需要解析 shared 的“请求”下嵌套更多的生命周期范围B
),那么您可能只是切换B
到InstancePerLifetimeScope()
:
builder.RegisterType<B>().InstancePerLifetimeScope();
这在很大程度上等同于每个请求,但也允许Owned<B>
由单例成功解决。
唯一需要注意的是,您必须小心不要意外地依赖B
其他地方的单例,因为这将不再被检测为错误。可以使用自定义来防止这种情况发生,IComponentLifetime
但除非您经常这样做,否则可能不值得付出努力。
于 2016-12-06T23:00:32.057 回答