Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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# 如何从实现接口的类调用新方法_C#_Dependency Injection - Fatal编程技术网

C# 如何从实现接口的类调用新方法

C# 如何从实现接口的类调用新方法,c#,dependency-injection,C#,Dependency Injection,如何调用在接口的具体类中实现的新方法 我正在使用结构图IOC容器 public interface ICompanyRepository { IEnumerable<Company> GetAll(); Company Get(int id); Company Add(Company item); bool Update(Company item); bool Delete(int id); } public class CompanyRep

如何调用在接口的具体类中实现的新方法 我正在使用结构图IOC容器

public interface ICompanyRepository
{
    IEnumerable<Company> GetAll();
    Company Get(int id);
    Company Add(Company item);
    bool Update(Company item);
    bool Delete(int id);
}

public class CompanyRepository: ICompanyRepository
{
   // Provide implementation for all interface  methods

//Class CompanyRepository will also have the new method called DisplayLog
    public void DisplayLog()
    {
        //To do
    }
}

在接口上,您只能调用接口中定义的内容—它是实现它的所有类的“公共基”的定义。问问你自己:如果你得到的
ICompanyRepository
是一种不实现
DisplayLog
的类型,该怎么办

这意味着:除了接口方法之外,不可能立即调用任何其他方法

要在
customerRepository
上调用
DisplayLog
,有三种方法:

  • DisplayLog()
    添加到界面
  • 将customerRepository转换为CompanyRepository。但是,如果customerRepository是CompanyRepository以外的任何其他类型,这将导致异常
  • 使用第二个接口
毕竟,我不太确定你所做的是否是DI。我对DI的理解应该是这样的:

public ActionResult Index(ILogDisplay display)
{
    var customers = display.DisplayLog(customerRepository);
    return View(customers);
}
ILogDisplay是一个新的接口,用于注入一个单独的类

public interface ILogDisplay 
{
    public YourResultType DisplayLog(ICustomerRepository);
}

在本例中,您实际上在类中注入了一个依赖项(ILogDisplay的实现)。

在接口上,您只能调用接口中定义的内容—它是实现它的所有类的“公共基”的定义。问问你自己:如果你得到的
ICompanyRepository
是一种不实现
DisplayLog
的类型,该怎么办

这意味着:除了接口方法之外,不可能立即调用任何其他方法

要在
customerRepository
上调用
DisplayLog
,有三种方法:

  • DisplayLog()
    添加到界面
  • 将customerRepository转换为CompanyRepository。但是,如果customerRepository是CompanyRepository以外的任何其他类型,这将导致异常
  • 使用第二个接口
毕竟,我不太确定你所做的是否是DI。我对DI的理解应该是这样的:

public ActionResult Index(ILogDisplay display)
{
    var customers = display.DisplayLog(customerRepository);
    return View(customers);
}
ILogDisplay是一个新的接口,用于注入一个单独的类

public interface ILogDisplay 
{
    public YourResultType DisplayLog(ICustomerRepository);
}

在本例中,您实际上在类中注入了依赖项(ILogDisplay的实现)。

这里有几个问题需要提出:

  • 为什么存储库知道如何显示日志
  • DisplayLog()
    在CustomerRepository的上下文中是什么意思
  • 为什么控制器甚至应该关心存储库记录的内容
  • 当返回类型明显为空时,为什么DisplayLog会分配一个名为customers的变量
  • 从根本上说,您的控制器应该不知道存储库的行为,这是控制反转原则的本质。它所关心的是,给定接口为存储库提供的显式契约,方法调用将返回客户。日志记录是存储库关心的问题

    从DI的角度来看,这是一种相当传统的设置,我们可以做到以下几点:

    ICompanyRepository:

    public interface ICompanyRepository() {
        IEnumerable<Company> GetAll();
        Company Get(int id);
        Company Add(Company item);
        bool Update(Company item);
        bool Delete(int id);
    }
    
    public class CompanyRepository: ICompanyRepository
    {
        private readonly ILogger logger;
    
        public CompanyRepository(ILogger logger) {
            this.logger = logger;
        }
        // Provide implementation for all interface  methods
    
        public Company Get(int id) {
    
            var customers = this.randomCustomerSource.Get(id);
            this.logger.Info("Whatever you want to log here");
            return customers;
        }
    }
    
    public class CustomerController {
        private readonly ICustomerRepository customerRepository;
    
        public CustomerController(ICustomerRepository CustomerRepository)
        {
            customerRepository = CustomerRepository;
        }
        // GET: Customers
        public ActionResult Index()
        {
            var customers = customerRepository.GetAll()
    
    
            return View(customers);
        }
    }
    
    客户控制器:

    public interface ICompanyRepository() {
        IEnumerable<Company> GetAll();
        Company Get(int id);
        Company Add(Company item);
        bool Update(Company item);
        bool Delete(int id);
    }
    
    public class CompanyRepository: ICompanyRepository
    {
        private readonly ILogger logger;
    
        public CompanyRepository(ILogger logger) {
            this.logger = logger;
        }
        // Provide implementation for all interface  methods
    
        public Company Get(int id) {
    
            var customers = this.randomCustomerSource.Get(id);
            this.logger.Info("Whatever you want to log here");
            return customers;
        }
    }
    
    public class CustomerController {
        private readonly ICustomerRepository customerRepository;
    
        public CustomerController(ICustomerRepository CustomerRepository)
        {
            customerRepository = CustomerRepository;
        }
        // GET: Customers
        public ActionResult Index()
        {
            var customers = customerRepository.GetAll()
    
    
            return View(customers);
        }
    }
    

    因此,存储库请求一个
    Ilogger
    ,控制器请求一个
    ICompanyRepository
    ,只需调用
    GetAll()
    并返回结果。通常会涉及更多的内容,但这是返回数据的控制器工作流程的基本要点。

    这里有几个问题需要提出:

  • 为什么存储库知道如何显示日志
  • DisplayLog()
    在CustomerRepository的上下文中是什么意思
  • 为什么控制器甚至应该关心存储库记录的内容
  • 当返回类型明显为空时,为什么DisplayLog会分配一个名为customers的变量
  • 从根本上说,您的控制器应该不知道存储库的行为,这是控制反转原则的本质。它所关心的是,给定接口为存储库提供的显式契约,方法调用将返回客户。日志记录是存储库关心的问题

    从DI的角度来看,这是一种相当传统的设置,我们可以做到以下几点:

    ICompanyRepository:

    public interface ICompanyRepository() {
        IEnumerable<Company> GetAll();
        Company Get(int id);
        Company Add(Company item);
        bool Update(Company item);
        bool Delete(int id);
    }
    
    public class CompanyRepository: ICompanyRepository
    {
        private readonly ILogger logger;
    
        public CompanyRepository(ILogger logger) {
            this.logger = logger;
        }
        // Provide implementation for all interface  methods
    
        public Company Get(int id) {
    
            var customers = this.randomCustomerSource.Get(id);
            this.logger.Info("Whatever you want to log here");
            return customers;
        }
    }
    
    public class CustomerController {
        private readonly ICustomerRepository customerRepository;
    
        public CustomerController(ICustomerRepository CustomerRepository)
        {
            customerRepository = CustomerRepository;
        }
        // GET: Customers
        public ActionResult Index()
        {
            var customers = customerRepository.GetAll()
    
    
            return View(customers);
        }
    }
    
    客户控制器:

    public interface ICompanyRepository() {
        IEnumerable<Company> GetAll();
        Company Get(int id);
        Company Add(Company item);
        bool Update(Company item);
        bool Delete(int id);
    }
    
    public class CompanyRepository: ICompanyRepository
    {
        private readonly ILogger logger;
    
        public CompanyRepository(ILogger logger) {
            this.logger = logger;
        }
        // Provide implementation for all interface  methods
    
        public Company Get(int id) {
    
            var customers = this.randomCustomerSource.Get(id);
            this.logger.Info("Whatever you want to log here");
            return customers;
        }
    }
    
    public class CustomerController {
        private readonly ICustomerRepository customerRepository;
    
        public CustomerController(ICustomerRepository CustomerRepository)
        {
            customerRepository = CustomerRepository;
        }
        // GET: Customers
        public ActionResult Index()
        {
            var customers = customerRepository.GetAll()
    
    
            return View(customers);
        }
    }
    

    因此,存储库请求一个
    Ilogger
    ,控制器请求一个
    ICompanyRepository
    ,只需调用
    GetAll()
    并返回结果。通常会涉及更多内容,但这是返回数据的控制器工作流程的基本要点。

    使用接口和DI的原因是,您不调用特定的实现,而是像代码一样调用接口。如果您真的想调用CompanyRepository方法,请创建一个硬耦合,而不要使用DI。但我听说,我们可以使用DI alsoadd void DisplayLog()来实现这一点?DI的目的是消除这种硬耦合。为什么要调用CompanyRepository类方法而不是使用接口?您真正想要的是什么还不清楚。还有什么是
    中的
    company2
    ,我需要调用company2的方法
    ?您可以从复习接口和DI的知识开始。以及如何使用结构映射。您使用接口和DI的原因是您不调用特定的实现,而是像代码一样调用接口。如果您真的想调用CompanyRepository方法,请创建一个硬耦合,而不要使用DI。但我听说,我们可以使用DI alsoadd void DisplayLog()来实现这一点?DI的目的是消除这种硬耦合。为什么要调用CompanyRepository类方法而不是使用接口?您真正想要的是什么还不清楚。还有什么是
    公司2
    我需要冰毒