Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 针对每个web请求和生命周期范围的SimpleInjector混合生活方式_C#_.net_Dependency Injection_Simple Injector - Fatal编程技术网

C# 针对每个web请求和生命周期范围的SimpleInjector混合生活方式

C# 针对每个web请求和生命周期范围的SimpleInjector混合生活方式,c#,.net,dependency-injection,simple-injector,C#,.net,Dependency Injection,Simple Injector,我使用SimpleInjector作为我的IoC容器,并采用以下技术为某些对象注册“混合”生活方式,包括每个web请求或每个线程 interface IUnitOfWork { } interface IWebUnitOfWork : IUnitOfWork { } interface IThreadUnitOfWork : IUnitOfWork { } class UnitOfWork : IWebUnitOfWork, IThreadUnitOfWork { } container.Re

我使用SimpleInjector作为我的IoC容器,并采用以下技术为某些对象注册“混合”生活方式,包括每个web请求或每个线程

interface IUnitOfWork { }
interface IWebUnitOfWork : IUnitOfWork { }
interface IThreadUnitOfWork : IUnitOfWork { }
class UnitOfWork : IWebUnitOfWork, IThreadUnitOfWork { }

container.RegisterPerWebRequest<IWebUnitOfWork, UnitOfWork>();
container.RegisterLifetimeScope<IThreadUnitOfWork, UnitOfWork>();
container.Register<IUnitOfWork>(() => container.GetInstance<UnitOfWork>());

// Register as hybrid PerWebRequest / PerLifetimeScope.
container.Register<UnitOfWork>(() =>
{
    if (HttpContext.Current != null)
        return container.GetInstance<IWebUnitOfWork>() as UnitOfWork;
    else
        return container.GetInstance<IThreadUnitOfWork>() as UnitOfWork;
});
接口IUnitOfWork{}
接口IWebUnitOfWork:IUnitOfWork{}
接口IThreadUnitOfWork:IUnitOfWork{}
类UnitOfWork:IWebUnitOfWork,IThreadUnitOfWork{}
container.registerWebRequest();
container.RegisterLifetimeScope();
container.Register(()=>container.GetInstance());
//注册为混合PerWebRequest/PerLifetimeScope。
容器。寄存器(()=>
{
if(HttpContext.Current!=null)
将container.GetInstance()作为UnitOfWork返回;
其他的
将container.GetInstance()作为UnitOfWork返回;
});
我对这个解决方案并不完全满意,因为对于每个需求,我必须定义额外的空接口,以使其工作,并确保它们被我的具体类引用

是否有任何理由我不应该使用以下扩展方法而不是定义额外的接口?如果这些方法存在一些问题,是否有其他方法完全可靠地确定我当前的容器实例正在IIS中运行

public static void RegisterHybridLifestyle<TService, TImplementation>(
    this Container container)
    where TService : class
    where TImplementation : class, TService
{
    if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
        container.RegisterPerWebRequest<TService, TImplementation>();
    else
        container.RegisterLifetimeScope<TService, TImplementation>();
}

public static void RegisterForLifestyle<TConcrete>(
    this Container container)
    where TConcrete : class
{
    if (HostingEnvironment.ApplicationHost != null)
        container.RegisterPerWebRequest<TConcrete>();
    else
        container.RegisterLifetimeScope<TConcrete>();
}
publicstaticvoidregisterhybridLifestyle(
这个集装箱(集装箱)
where-TService:class
实施地点:类别、服务
{
if(System.Web.Hosting.HostingEnvironment.ApplicationHost!=null)
container.registerWebRequest();
其他的
container.RegisterLifetimeScope();
}
公共静态无效注册表项样式(
这个集装箱(集装箱)
其中t混凝土:类
{
if(HostingEnvironment.ApplicationHost!=null)
container.registerWebRequest();
其他的
container.RegisterLifetimeScope();
}

更新

上述问题基于对SimpleInjector和混合注册的误解。上面和其他地方描述的技术适用于容器可以为Web请求和不在Web请求上下文中运行的后台进程的请求提供服务的情况。我一直在尝试实现的是变量注册,以适应既适合Web请求又适合线程请求的容器配置。i、 e.我需要将容器配置为在IIS中工作和在windows服务中工作。我不需要动态注册,可以同时满足两者的需求

其结果是以下扩展方法,我已从解决方案中删除了“额外”接口:-)

publicstaticvoidregisterforscope(此容器)
where-TService:class
实施地点:类别、服务
{
if(System.Web.Hosting.HostingEnvironment.ApplicationHost!=null)
container.registerWebRequest();
其他的
container.RegisterLifetimeScope();
}
公共静态无效注册表ForScope(此容器)
其中t混凝土:类
{
if(System.Web.Hosting.HostingEnvironment.ApplicationHost!=null)
container.registerWebRequest();
其他的
container.RegisterLifetimeScope();
}
我对这个解决方案并不完全满意

是的,我同意这一点。老实说,必须这样做实际上让IMO很糟糕。这就是为什么在SimpleInjector 2.0中固定了这一点。它包含明确的生活方式概念,并将包含
生活方式.CreateHybrid
方法,这使得注册混合生活方式更加容易

然而,你似乎并不需要一种混合的生活方式。混合生活方式是一种可以动态切换的生活方式(每次调用
GetInstance
和每次注入),而您似乎只需要在启动期间切换。我认为使用您定义的
RegisterHbridLifestyle
扩展方法没有什么害处,但请记住,这并不是一种真正的混合生活方式(因此名称有点误导),而只是一个配置/部署开关

简单的喷油器2和以上使这更容易,它将允许您执行以下操作:

//根据部署定义一次生活方式。
Container.Options.DefaultScopedLifestyle=
生活方式(
生活方式选择器:HostingEnvironment.ApplicationHost!=null,
trueLifestyle:new WebRequestLifestyle(),
falseLifestyle:new LifetimeScope Lifestyle());
//并用它来登记工作单位
//(不再需要额外的接口)。
容器。寄存器(生活方式。范围);
//设置DefaultScopedLifestyle后,可以使用usr Lifestyle.Scoped
container.RegisterCollection(
类型(ISubscriber),
新[]{typeof(ISubscriber.Assembly},
生活方式(范围);

我在这里发布了一个后续问题,我期待着2.0版,并将尽快升级!
public static void RegisterForScope<TService, TImplementation>(this Container container)
    where TService : class
    where TImplementation : class, TService
{
    if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
        container.RegisterPerWebRequest<TService, TImplementation>();
    else
        container.RegisterLifetimeScope<TService, TImplementation>();
}

public static void RegisterForScope<TConcrete>(this Container container)
    where TConcrete : class
{
    if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
        container.RegisterPerWebRequest<TConcrete>();
    else
        container.RegisterLifetimeScope<TConcrete>();
}