相关疑难解决方法(0)

虚拟成员在构造函数中调用

我从ReSharper收到一条关于从我的对象构造函数调用虚拟成员的警告.

为什么不做这件事?

c# resharper constructor warnings virtual-functions

1270
推荐指数
11
解决办法
17万
查看次数

依赖注入(DI)"友好"库

我正在思考一个C#库的设计,它将有几个不同的高级函数.当然,这些高级功能将尽可能使用SOLID类设计原则来实现.因此,可能存在供消费者定期直接使用的类,以及作为那些更常见的"最终用户"类的依赖性的"支持类".

问题是,设计库的最佳方法是:

  • DI不可知 - 虽然为一个或两个常见的DI库(StructureMap,Ninject等)添加基本的"支持"似乎是合理的,但我希望消费者能够将该库与任何DI框架一起使用.
  • 非DI可用 - 如果库的使用者没有使用DI,那么库应该仍然尽可能容易使用,减少了用户为创建所有这些"不重要"的依赖关系而必须完成的工作量.他们想要使用的"真实"类.

我目前的想法是为常见的DI库提供一些"DI注册模块"(例如,一个StructureMap注册表,一个Ninject模块),以及一个非DI的集合或工厂类,并包含与这几个工厂的耦合.

思考?

c# dependency-injection inversion-of-control

227
推荐指数
2
解决办法
4万
查看次数

"Bastard Injection"和"Poor Man's Injection"之间的真正区别是什么?

从".Net中的依赖注入"一书中我知道应该在应用程序的组合根处创建对象图,这对我来说在使用IoC容器时很有意义.

在我尝试使用DI时所见到的所有应用程序中,总有两个构造函数:一个具有依赖关系作为参数的构造函数和一个没有参数的"默认"构造函数,而这些构造函数又调用另一个"newing"所有的依赖关系,但在上述书中,这被称为"混蛋注射反模式",这就是我曾经知道的"穷人的注射".

现在考虑所有这些,我会说"穷人注射"只是不使用IoC容器而是在所述组合根上手动编码所有对象图.

所以我的问题是:

  1. 我是否正确理解了这些概念,还是完全偏离了轨道?
  2. 如果您仍然需要在IoC容器中注册所有依赖项,而不是在完全相同的组合根中手动编码,那么使用IoC容器的真正好处是什么?
  3. 如果我误解了"穷人的注射"究竟是什么,有人可以澄清一下吗?

谢谢

architecture oop dependency-injection

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

Mark Seemann关于Bastard Injection的相互矛盾的陈述.需要一些澄清

我正在阅读他的书" 网上依赖注入".

1)他在这里Bastard Injection只有在我们使用时才会发生Foreign Default.

但在他的书中,第148页上的插图显示,Bastard Injection当依赖项的默认实现是Foreign Default或者Local Default:

在此输入图像描述

那么当依赖的默认实现是一个时,Bastard Injection反模式也会出现Local Default吗?

2)在这里(以及他的书中)他指出,如果一个类有一个可选的依赖,那么这个依赖的默认实现是好的Local Default:

但在下一篇文章中,他似乎反对拥有可选的依赖项,即使默认实现Local Default:

private readonly ILog log;
public MyConsumer(ILog log)
{
    this.log = log ??LogManager.GetLogger("My");
}
Run Code Online (Sandbox Code Playgroud)

就封装而言,这种方法的主要问题在于,看起来MyConsumer类无论是否控制其日志依赖的创建都无法真正决定.虽然这是一个简化的示例,但如果LogManager返回的ILog实例包装了一个非托管资源,这可能会成为问题,该资源应该在不再需要时处理掉.

当依赖的默认实现是本地的时,他在上面的摘录中的参数是否也有效?如果是这样,那么还应该避免使用具有本地默认值的可选依赖项?

3)Pg.147:

Bastard Injection的主要问题是它使用了FOREIGN DEFAULT ...,我们不能再自由地重用该类了,因为它拖拽了我们可能不想要的依赖.进行并行开发也变得更加困难,因为类很大程度上依赖于它的依赖性.

Foreign Default是一个依赖项的实现,它被用作默认值,并在与其使用者不同的程序集中定义.因此,对于Foreign Default,使用者的程序集也会依赖于依赖项的程序集.

他是否也暗示Foreign Default使并行开发更加困难,而Local Default则不然?如果他是,那么这没有意义,因为我认为使并行开发变得困难的原因并不是消费者的集合很难引用依赖的汇编,而是消费者阶层依赖于一个具体实现的事实.依赖?

谢谢

dependency-injection

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

这是"混蛋注射反模式"的一个很好的例子吗?

我看到首席开发人员编写这样的代码并在阅读Mark Seemann的书".NET中的依赖注入"时,我想知道特定的"新"是否是"外来的",因此"Bastard Injection"?

public class SessionInitServiceManager
{
    protected readonly ICESTraceManager _traceManager;
    protected readonly ILogger _logger;
    protected readonly IAggregateCalls _aggregator;
    protected readonly IMultiCoreRepository _repository;

    public SessionInitServiceManager(ICESTraceManager traceManager,
                                     ILogger logger,
                                     IAggregateCalls aggregator,
                                     IMultiCoreRepository repository)
    {
        _traceManager = traceManager;
        _logger = logger;
        _aggregator = aggregator;
        _repository = repository;
    }

    public SessionInitServiceManager() : this(new CESTraceManager(),
                                              new Logger("BusinessServices.authenticateUser"),
                                              new Aggregator(),
                                              new RepositoryFactory().BuildMultiCoreRepository()) { }
Run Code Online (Sandbox Code Playgroud)

c# constructor dependency-injection inversion-of-control

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

自动化测试中的DbContext.ChangeTracker会抛出SQLException

我正在为一个我正在努力的项目编写自动化测试,以便更熟悉MVC,EntityFramework(代码优先),单元测试和Moq.

我的类中有一个部分,Repository它设置了LastModified我的模型的一个区域,只要Repository.SaveChanges()控制器调用它就像这样工作(MyModelBase是一个基类):

public void RepoSaveChanges()
{
    foreach(var entry in _dbContext.ChangeTracker.Entities().Where(e => e.State == EntityState.Modified))
    {
        MyModelBase model = entry.Entity as MyModelBase;
        if (model != null)
        {
            model.LastModified = DateTime.Now;
        }
    }
    _dbContext.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

这在正常在线环境中的应用程序运行时期间工作正常,但在测试方法中运行时会中断.我使用Moq来模拟DbContext中的DbSets并设置我的测试数据.

这是我的奇怪部分:我的单元测试运行正常(通过)但它们实际上并没有真正进入foreach循环 - 它在ChangeTracker.Entities()被访问时挂起并退出循环,向下跳转到_dbContext.SaveChanges().没有错误.

但是,在与我共享项目的朋友的机器上,ChangeTracker.Entities()访问时会收到SQLException .我确实在VS2015中检查了SQLExceptions,并且没有输出或其他异常指示.

结果StackTrace:
在System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,UInt32 waitForMultipleObjectsTimeout,Boolean allowCreate,Boolean onlyOneCheckConnection,DbConnectionOptions userOptions,DbConnectionInternal&connection)....

结果消息:
测试方法MyProject.Tests.TestClasses.MyControllerTests.TestCreate引发异常:System.Data.SqlClient.SqlException:建立与SQL Server的连接时发生与网络相关或特定于实例的错误.服务器未找到或无法访问.验证实例名称是否正确,以及SQL Server是否配置为允许远程连接.(提供程序:SQL网络接口,错误:26 - 查找指定的服务器/实例时出错)

最后,我的问题是:有没有办法使用Moq模拟ChangeTracker(我怀疑不是来自之前的调查),还是我可以采取另一种方法来RepoSaveChanges()自动设置属性?如果没有访问,ChangeTracker.Entities()我需要有更新逻辑来LastModified为每个拥有它的模型类型设置字段.同样,我觉得避免使用该API /框架的一部分,因为测试是顽固的并不理想.

有没有人知道为什么没有抛出/不能在我的机器上捕获SQLException?或者有关如何ChangeTracker.Entities()在单元测试中使用的任何建议?LastModified作为最后的手段,我只会在所有模型和控制器上单独设置属性.

更新: …

c# asp.net-mvc unit-testing entity-framework moq

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

ASP.NET MVC Web项目中的单元测试类是一个很好的例子吗?

我正在学习TDD.我知道依赖注入,你将类的依赖项放在构造函数的参数中并传入它们,从默认构造函数传递默认实现,例如;

public AccountController() : this( RepositoryFactory.Users())
{
}

public AccountController( IUserRepository oUserRepository)
{
 m_oUserRepository = oUserRepository;
}
Run Code Online (Sandbox Code Playgroud)

RepositoryFactory是一个简单的静态类,它返回当前构建的所选实现

但默认的ASP.NET MVC Web应用程序项目不会这样做,而是DI采用在测试类中的对象初始值设定项中分配的公共属性的形式,例如; 来自AccountController.cs:

protected override void Initialize(RequestContext requestContext)
{
 if (FormsService == null)
  { FormsService = new FormsAuthenticationService(); }
 if (MembershipService == null)
  { MembershipService = new AccountMembershipService(); }

 base.Initialize(requestContext);
}
Run Code Online (Sandbox Code Playgroud)

在测试类AccountControllerTest.cs中:

private static AccountController GetAccountController()
{
 AccountController controller = new AccountController()
 {
  FormsService = new MockFormsAuthenticationService(),
  MembershipService = new MockMembershipService(),
  Url = new UrlHelper(requestContext),
 };
 //snip
}
Run Code Online (Sandbox Code Playgroud)

所以现在我的AccountController类有两种依赖注入方法.我应该使用哪一个?构造函数注入或公共属性?

我在考虑构造函数注入...

ASP.NET …

c# tdd asp.net-mvc dependency-injection

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

混凝土.Net类的依赖注入

注入/隔离密封在dll中并且不实现接口的类的首选方法是什么?

我们使用Ninject.

假设我们有一个类"Server",我们想要注入/隔离"Server"使用的类TcpServer.

不想太具体,因为我想知道最好的方法,但让我们这样说:

public class Server 
{
    IServer _server;
    public Server(IServer server) 
    { 
        _server = server;
    }

    public void DoSomething()
    {
        _server.DoSomething();     
    }
}
Run Code Online (Sandbox Code Playgroud)

_server 在测试的情况下,应该注入TcpClient或mock

.net c# dependency-injection ninject

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

测试友好的架构

我有一个关于设计类的最佳方法的问题,以便测试友好.假设我有一个OrderService类,用于下订单,检查订单状态等等.该类需要访问客户信息,库存信息,发货信息等.因此OrderService类将需要使用CustomerService,InventoryService和ShippingService.每个服务也有自己的后备存储库.

设计OrderService类以便轻松测试的最佳方法是什么?我见过的两种常用模式是依赖注入和服务定位器.对于依赖注入,我会做这样的事情:

class OrderService
{
   private ICustomerService CustomerService { get; set; }
   private IInventoryService InventoryService { get; set; }
   private IShippingService ShippingService { get; set; }
   private IOrderRepository Repository { get; set; }

   // Normal constructor
   public OrderService()
   {
      this.CustomerService = new CustomerService();
      this.InventoryService = new InventoryService();
      this.ShippingService = new ShippingService();
      this.Repository = new OrderRepository();         
   }

   // Constructor used for testing
   public OrderService(
      ICustomerService customerService,
      IInventoryService inventoryService,
      IShippingService shippingService,
      IOrderRepository repository)
   {
      this.CustomerService = customerService;
      this.InventoryService = inventoryService;
      this.ShippingService = …
Run Code Online (Sandbox Code Playgroud)

c# testing unit-testing dependency-injection service-locator

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