小编Ste*_*ven的帖子

OWIN中间件+ Web API +简单注入器

我目前正在使用WebApiRequestLifestyle具有默认的范围生活方式.我想在OWIN中间件和其中一个API控制器中注入一个服务,服务的范围应该仍然是WebAPI,即对于整个请求,应该只有一个服务实例.

public class TestMiddleware : OwinMiddleware
{
    private readonly ITestService _testService;

    public TestMiddleware(OwinMiddleware next, ITestService testService) : base(next)
    {
        _testService = testService;
    }

    public override async Task Invoke(IOwinContext context)
    {
        var test = _testService.DoSomething();
        await Next.Invoke(context);
    }
}

public class ValuesController : ApiController
{
    private readonly ITestService _testService;

    public ValuesController(ITestService testService)
    {
        _testService = testService;
    }
}
Run Code Online (Sandbox Code Playgroud)

整个请求的ITestService实例应该相同.我该如何注册中间件?

这就是我现在这样做的方式:

     using (container.BeginExecutionContextScope())
        {
            var testService = container.GetInstance<ITestService>();
            app.Use<TestMiddleware>(testService);
        }
Run Code Online (Sandbox Code Playgroud)

这种方法的问题是 - 在注册期间为中间件创建一个ITestService实例并永久保留(如单例),并且对于每个webapi请求,都会在控制器之间创建和共享新实例(webapi范围)

请不要指出这些问题 - WebApi + Simple Injector + OWIN

使用Simple …

c# dependency-injection simple-injector asp.net-web-api owin

1
推荐指数
1
解决办法
1802
查看次数

使用通用存储库实现简单注入器

我在使用通用存储库实现 SimpleInjector 时遇到一些问题。

我有一个接口和一个实现该接口的IRepository<T> where T : class抽象类。abstract class Repository<C, T> : IRepository<T> where T : class where C : DbContext最后,我有了继承抽象类的实体存储库。这是一个具体的例子:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Remove(T entity);
}


public abstract class Repository<C, T> : IRepository<T> 
    where T : class where C : DbContext, new()
{
    private C _context = new C();
    public C Context
    {
        get { return _context; }
        set { …
Run Code Online (Sandbox Code Playgroud)

c# generics dependency-injection simple-injector

1
推荐指数
1
解决办法
1493
查看次数

我应该在界面或抽象背后隐藏DTO和View Models吗?

使用IoC可解析接口来指定DTO有什么价值吗?

Fer示例:

private readonly IGetTransactionsQuery _query;
private readonly ICreateTransactionCommand _createCommand;

public TransactionsController(
    IGetTransactionsQuery query,
    ICreateTransactionCommand createCommand)
{
    _query = query;
    _createCommand = createCommand;
}

[EnableQuery]
public IQueryable<ITransactionQueryModel> Get()
{
    return _query.Execute();
}

public async Task<IHttpActionResult> Post(ICreateTransactionModel transaction)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    await _createCommand.Execute(transaction);
    return Created(transaction);
}
Run Code Online (Sandbox Code Playgroud)

在这里,我使用的是ITransactionQueryModel和ICreateTransactionModel,而不是结核.这里有商业价值吗?哪种方案可以从这种方法中受益?我可以想到一些,但希望得到一些用例场景的共识

注意:我只是指控制器"动作"方法,而不是构造函数,因为IoC的好处是显而易见的

c# dependency-injection asp.net-web-api

1
推荐指数
1
解决办法
185
查看次数

IoC实例化最新时间

在我的应用程序中,我有许多服务,我使用以下模式:在与接口相同的文件中,我定义了一个静态工厂方法,该方法由IoC容器控制,如下所示:

public interface ISomethingService {
    Task DoSomethingAsync(int id);
}

public class SomethingServicFactory : ServiceFactory<ISomethingService > { }

public class ServiceFactory<T>
{
    public static Func<T> CreateClosure;
    public T GetDefault() => CreateClosure();
}
Run Code Online (Sandbox Code Playgroud)

创建和配置IoC容器后:

SomethingServicFactory .CreateClosure = () => 
    Container.GetInstance<ISomethingService >();
Run Code Online (Sandbox Code Playgroud)

稍后在我的应用程序中,当我需要SomethingService时:

var somethingService= new SomethingService().GetDefault();
Run Code Online (Sandbox Code Playgroud)

这允许我将创建推迟到最后一刻,但仍然使用容器控制服务创建.我刚开始使用SimpleInjector.更重要的是,它允许我创建服务实例并轻松传递参数,同时控制IoC.

这个模式帮助我的一个很好的例子是WPF XAML实例化的用户控件,它需要填充数据(即数据库中的查找值).在后面的代码中,我能够轻松地创建DbContext并从数据库中获取数据.但是,我也开始在整个应用程序中使用它.

我担心通过使用这种模式我错过了重大的设计/架构问题,我正在寻找IoC专家对此模式的评论.

c# ioc-container inversion-of-control simple-injector

1
推荐指数
1
解决办法
59
查看次数

通过通用接口/抽象类实现使.NET Core DI自动解析类

.NET Core中是否有一种方法可以注册通用接口,并使其解析与某个实现相匹配的类.

例如,我有以下界面:

public interface IMapper<TFrom, TTo>
{
}
Run Code Online (Sandbox Code Playgroud)

我还有一个抽象类:

public abstract class Mapper<TFrom, TTo> : IMapper<TFrom, TTo>
{
    protected Mapper()
    {
        // some generic stuff
    }

    public abstract TTo Map(TFrom);
}
Run Code Online (Sandbox Code Playgroud)

然后我可以创建一个这样的实现:

public class UserMapper : Mapper<Domain.User, Entity.User>
{
    public override Entity.User Map(Domain.User from)
    {
        // do mapping
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法,使用默认的.NET Core DI进行注册IMapper<,>,让它自动解析类?

所以,例如,如果我在代码中的某个地方执行此操作:

class SomeClass
{
    public SomeClass(IMapper<Domain.User, Entity.User> mapper) {}
}
Run Code Online (Sandbox Code Playgroud)

它以某种方式知道它应该解决这个类UserMapper<Domain.User, Entity.User>

原因是手动注册每个映射器有点冗长,特定于实现.所以我希望Microsoft.DependencyInjection能够以某种方式自动解决其实现.

c# dependency-injection inversion-of-control .net-core

1
推荐指数
1
解决办法
2508
查看次数

通过本机 .NET Core 依赖注入构建组合

如何创建像下面的示例一样的复合实现,但使用本机 .NET Core DI 容器?

\n\n
    [TestFixture]\n    public class CompositeTests\n    {\n        [Test]\n        public void BuildComposite()\n        {\n            var container = new UnityContainer();\n            container.RegisterType<IFoo, SomeFoo>("first");\n            container.RegisterType<IFoo, AnotherFoo>("second");\n            container.RegisterType<IFoo, CompositeFoo>();\n\n            var instanceOfFoo = container.Resolve<IFoo>();\n\n            Assert.IsInstanceOf<CompositeFoo>(instanceOfFoo);\n        }\n    }\n\n    public class CompositeFoo : IFoo\n    {\n        public CompositeFoo(IFoo[] others)\n        {\n            Debug.Assert(others != null);\n            Debug.Assert(others.Any());\n        }\n    }\n\n    public class AnotherFoo : IFoo {}\n    public class SomeFoo : IFoo {}\n    public interface IFoo {}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

在这种情况下,复合\xe2\x80\x9c消耗\xe2\x80\x9d子对象的数组,并且在某种意义上\xe2\x80\x9csucks在\xe2\x80\x9d中使用密钥注册的IFoo的每个实现。\这是一个重要的方面:如果您要使用键注册组合,它将尝试实例化自身,从而立即导致 StackOverflowException。

\n
\n\n

本机 DI 不支持这些命名注册。

\n\n

这个例子是从这里提取的

\n

c# dependency-injection composite ioc-container .net-core

1
推荐指数
1
解决办法
1063
查看次数

在 Web 表单中创建自定义简单注入器作用域

我的 Windows 窗体应用程序中有一个文本框和一个按钮。当使用文本框中写入的值按下开始键时,应使用该值打开一个新表单。我想为每个打开的表单创建一个范围。当我关闭表单时,我想关闭相关范围。

如何使用简单的注入器创建自定义范围?

这是一个简单的示例代码

static class Program
{
    static readonly Container container;

    static Program()
    {
        container = new Container();

        container.Register<MyProgram>();
        //??
        container.Register<MyCustomClass>(Lifestyle.Scoped);

        container.Verify();
    }

    static void Main()
    {
        //Something...
    }
}

class User
{
    public int UserID { get; set; }
    public string UserName { get; set; }
}

class MyCustomClass
{
    User _user;
    public MyCustomClass(User user)
    {
        _user = user;
    }

    public void Print()
    {
        Console.WriteLine(_user.UserName);
    }
}    

class MyProgram
{
    public void StartNewScope(string username, int userid)
    { …
Run Code Online (Sandbox Code Playgroud)

.net c# dependency-injection winforms simple-injector

1
推荐指数
1
解决办法
1793
查看次数

'ServiceCollection'不包含'AddSingleton'的定义

我一直在通过程序类向我的IOC容器注册我的依赖项,但它变得很乱.我决定编写一个DI提供程序,它提供并注册了它内部的依赖项.

在我开始用代码解释之前,这是VS给出的完整编译错误.

'ServiceCollection'不包含'AddSingleton'的定义无法解析符号'AddSingleton'

我尽量保持干净,在里面加入ServiceCollection类 DependencyProvider

public class DependencyProvider : ServiceCollection, IDependencyProvider
{
    public DependencyProvider() : base()
    {
        Register();
    }

    public void Register()
    {
        base.AddSingleton<IContext, Context>(); // this line errors
        new ServiceCollection().AddSingleton<IContext, Context>(); // this line works
    }
}
Run Code Online (Sandbox Code Playgroud)

这是IDependencyProvider接口

public interface IDependencyProvider : IServiceCollection
{
    void Register();
}
Run Code Online (Sandbox Code Playgroud)

我可以不这样做,还是我只是做错了什么?我真的希望它可能,因为解决方案看起来非常干净,请创建一个新的ServiceCollection实例并使用该字段.

只是为了澄清错误,我无法访问任何基本方法ServiceCollection,就像这样

base.AddSingleton<IContext, Context>();
Run Code Online (Sandbox Code Playgroud)

但是,这条线在内联新实例时起作用

new ServiceCollection().AddSingleton<IContext, Context>();
Run Code Online (Sandbox Code Playgroud)

.net c# asp.net dependency-injection

1
推荐指数
1
解决办法
432
查看次数

Java Guice DI错误:UnsatisfiedDependencyException:SystemInjecteeImpl中没有可用于注入的对象

我有一个使用Jersey 2.x的简单REST API项目.我尝试使用Google Guice来注入我的依赖项,但它似乎不起作用.我收到此错误:

org.glassfish.hk2.api.UnsatisfiedDependencyException:SystemInjecteeImpl没有可用于注入的对象(r​​equiredType = AccountService,parent = AccountsResource,qualifiers = {},position = 0,optional = false,self = false,unqualified = null,1658198405 )

我有这个简单的资源类

@Path("/accounts")
@Produces(MediaType.APPLICATION_JSON)

public class AccountsResource {

    private final AccountService accountService;

    @Inject
    public AccountsResource(AccountService accountService) {
        this.accountService = accountService;
    }

  @GET
  @Path("test")
  public String test() {
    return this.accountService.test();
  }
Run Code Online (Sandbox Code Playgroud)

我想将此服务注入我的资源类

public class AccountService {

    public AccountService() {}

    public String test() {
        return "test";
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,按照Guice的指南,我创建了这个模块类

import com.google.inject.*;

public class AccountsResourceModule extends AbstractModule  {

@Override
protected void configure() {
    bind(AccountService.class); …
Run Code Online (Sandbox Code Playgroud)

java dependency-injection jax-rs jersey guice

1
推荐指数
1
解决办法
866
查看次数

带有简单注入器的 Legacy .NET 应用程序中的选项模式、配置

这篇文章https://medium.com/@dmitryzaets/legacy-net-applications-configuration-management-net-framework-4-5-1-68220335d9d8描述了如何将选项模式与 Autofac 一起使用。我试图将其翻译为与 Simple Injector 一起使用。但我没有运气。这是我的国际奥委会代码

public class IocBootstrap2
{
    private Container Container { get; }
    public IocBootstrap2()
    {
        Container = new Container();
        var configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Configuration"))
            .AddJsonFile("settings.json", optional: false, reloadOnChange: true);
        var configuration = configurationBuilder.Build();
        //Register Options
        Container.Register(typeof(IOptions<>), typeof(OptionsManager<>));
        Container.Register(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>));
        Container.Register(typeof(IOptionsFactory<>), typeof(OptionsFactory<>));
        Container.Register(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>));
        // Register ConfigurationOptions
        Container.RegisterConfigurationOptions2<MailingOptions>(configuration.GetSection("mailing"));

    #if DEBUG
        Container.Verify();
    #endif   
 }
}

public static class ConfigurationSetupExtensions2
{
    public static void RegisterConfigurationOptions2<TOptions>(this Container container, IConfiguration config)
        where TOptions : class
    {
        container.Register(typeof(IOptionsChangeTokenSource<TOptions>), …
Run Code Online (Sandbox Code Playgroud)

configuration configurationmanager legacy-code simple-injector .net-core-configuration

1
推荐指数
1
解决办法
1268
查看次数