IoC和绑定到接口

时间:2014-02-05 19:37:42

标签: c# dependency-injection inversion-of-control

请原谅一个真实但n00b级别的查询。我正在做一个新项目并开始在IoC方面进行烘焙。这是我第一次参与构建框架的工作,所以我在某种程度上用IoC切割了我的牙齿。我正在采取一个强烈的建议来使用Ninject。凉。

但是当我坐下来创建我依赖构造函数注入的第一个类时,它让我感到震惊 - 我仍然需要在构造函数中使用所有这些非常自定义/第三方接口。那么,如果我的类在构造函数中都采用了log4net ILog实例,那么我的代码与log4net的耦合程度如何呢?我仍然需要在每个要记录任何内容的文件中使用log4net的using语句。

我认为 是你的大量类的抽象和解耦,并将所有的依赖推送到一个类中。在我看来,每个想要记录任何内容的类仍然完全绑定到log4net,并且将log4net更改为另一个记录器将是乏味的。这怎么会赢?

我确定我错过了什么,所以帮帮我吧?我是想创建自己的接口,我希望真正解耦,然后为实现添加适配器或什么?只有这样,我们似乎才将所有依赖项推送到一个区域。

2 个答案:

答案 0 :(得分:1)

如果使用IOC,则将接口注入到类中,而不是实现,这样就可以了。要解决您的特定问题,请尝试查看通用日志记录框架(http://netcommon.sourceforge.net/),它本身就是log4net或许多其他日志记录框架的包装器。

这将您与常见的日志记录框架结合在一起,但它使用得非常广泛,稳定并且可以抽象记录特定的日志记录,而无需您自己执行任何操作。

当我以前使用它时,我使用post build脚本将log4net程序集放入输出目录,因此绑定仅在运行时发生。出于测试目的,就代码而言,您正在通过提供的公共接口与通用日志记录框架进行交流。

答案 1 :(得分:0)

我知道你在说什么!你将进行一种推广以减少代码重复(我正在跳跃)。当你使用.net框架时,我不得不说默认情况下它不支持面向方面编程,让你在每种情况下表现不同。例如,看一下这段代码:

public class BlogService : IBlogService
    {
        private readonly IBlogRepository _blogRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly ILogger _logger;

        public BlogService(
            IBlogRepository blogRepository,
            IUnitOfWork unitOfWork,
            ILogger logger)
        {
            _blogRepository = blogRepository;
            _unitOfWork = unitOfWork;
            _logger = logger;
        }

   public GetAllBlogPostResponse GetAllBlogPost(GetAllBlogPostRequest request)
        {
            var response = new GetAllBlogPostResponse();
            try
            {
                var blogPosts = _blogRepository.GetAll();
                if (blogPosts != null)
                {
                    response.BlogPostViewModel = blogPosts.ConvertToPostListViewModel();
                    response.Success = true;
                    response.MessageType = MessageType.Success;
                    response.Message =       ServiceMessages.GeneralServiceSuccessMessageOnRetrieveInformation;
                    _logger.Log(string.Format(response.Message));
                }
                else
                {
                    response.MessageType = MessageType.Info;
                    response.Message = ServiceMessages.GeneralServiceAlarmMessageOnRetrieveInformation;
                    _logger.Log(string.Format(response.Message));
                }
            }
            catch (Exception exception)
            {
                response.Success = false;
                response.Message = ServiceMessages.GeneralServiceAlarmMessageOnRetrieveInformation;
                _logger.Log(string.Format(response.Message));
                _logger.Log(exception.Message);
            }
            return response;
        }

我已在我的应用程序的每个服务类中注入了IBlogRepository,IUnitOfWrork和ILogger(Log4net)。而不是我在每个catch语句中都有类似的响应和通用消息。一旦我想进行各种泛化而不是在每个服务类中重新实现类似的代码,但是在这种情况下进行泛化将更具成本效益和困难。虽然在某些情况下不重复代码非常重要,例如我有这个BaseController并从中派生出我的所有控制器:

public class BaseController : Controller
    {
        private readonly ICookieStorageService _cookieStorageService;
        private readonly ILanguageService _languageService;

        public BaseController(ICookieStorageService cookieStorageService,ILanguageService languageService)
        {
            _cookieStorageService = cookieStorageService;
            _languageService = languageService;
        }
    }

所以我不需要每次都在我的控制器中创建cookieStorageService和languageService,因为我已经实现了一次。