【问题标题】:interfaces and classes in C#C#中的接口和类
【发布时间】:2014-01-25 17:27:59
【问题描述】:

我收到以下错误:

test.Services.JobService' 不包含一个构造函数 0 个参数。

这是代码:

JobService.cs:

namespace TesteUltrafan.Services
{
    public class JobService
    {
        private readonly IRepository _repository;

        public JobService(IRepository repository)
        {
            _repository = repository;
        }

        public Job CreateJobBanker()
        {
            var banker = new Job();

            string id = Guid.NewGuid().ToString("N");

            Console.WriteLine("Novo job banker id: {0}", id);

            banker.Id = id;
            banker.Type = JobType.Banker;
            banker.CreatedAt = DateTime.Now;

            Console.WriteLine("Salvando job banker id: {0}", id);

            Job jobBanker = _repository.SaveJob(banker);

            return jobBanker;
        }
    }
}

程序.cs:

public class Program
{
    public static void Main()
    {
        var jobService = new JobService(); <---- Here is the error.

        Console.WriteLine("Creating job banker, creation:");

        Job jobBanker = jobService.CreateJobBanker();

        Console.WriteLine("Job banker: {0}", jobBanker);
    }
}

Job.cs:

public class Job
{
    public string Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public JobType Type { get; set; }
}

JobType.cs:

public enum JobType
{
    Actor = 1,
    Agricultural = 2,
    Banker = 3,
    EngineerCivil = 4,
    Another = 5,
}

【问题讨论】:

  • 缺少默认构造函数。
  • 这是 IRepository: public interface IRepository { Job SaveJob(Job job); }

标签: c# class interface repository


【解决方案1】:

您要么需要在 JobService 类中创建一个无参数构造函数(我不会这样做,因为这样您的类将无法正常工作 - 将不会引用任何存储库),或者最好将 Repository 实例作为参数传递在构造这个实例时。

所以代码最好如下所示:

public class Program
{
    public static void Main()
    {
        var jobService = new JobService(new Repository()); 

        Console.WriteLine("Creating job banker, creation:");

        Job jobBanker = jobService.CreateJobBanker();

        Console.WriteLine("Job banker: {0}", jobBanker);
    }
}

其中Repository 应该是实现IRepository 接口的类。如果不通过此实例,您的 CreateJobBanker 将无法工作。

尽管推荐使用一些 IoC 容器,因为您的代码遵循控制反转原则(可能您甚至不知道这一点)。

【讨论】:

    【解决方案2】:

    使用

    var jobService = new JobService(new Repository());
    

    因为否则您的JobService 没有IRepository 实例,并且当您尝试在JobService 中使用您的存储库时会抛出NullReferenceException

    在您的代码中,您正在初始化 JobService 而不给它一个 IRepository 参数,要编译您的代码,您需要在 JobService 中定义一个没有 IRepository 参数的构造函数这样做:

    public class JobService
    {
        private readonly IRepository _repository;
    
        // New Constructor will make _repository null
        public JobService()
        {           
        }
    
        public JobService(IRepository repository)
        {
            _repository = repository;
        }
    
        public Job CreateJobBanker()
        {
            var banker = new Job();
    
            string id = Guid.NewGuid().ToString("N");
    
            Console.WriteLine("Novo job banker id: {0}", id);
    
            banker.Id = id;
            banker.Type = JobType.Banker;
            banker.CreatedAt = DateTime.Now;
    
            Console.WriteLine("Salvando job banker id: {0}", id);
    
            // NullReferenceException if you define a parameterless constructor
            Job jobBanker = _repository.SaveJob(banker);
    
            return jobBanker;
        }
    }
    

    现在您可以通过两种方式构建它:

    var jobService = new JobService();
    

    var jobService = new JobService(new Repository());
    

    IRepository 实现:

    public class Repository: IRepository
    {
       private MyDbEntities context = new MyDbEntities();
    
       public Job SaveJob(Job job)
       {
           // assuming Entity Framework
           var id = job.Id;
           if (context.Jobs.Any(e => e.Id == id))
           {
               context.Jobs.Attach(job);
               context.ObjectStateManager.ChangeObjectState(jobs, EntityState.Modified);
           }
           else
           {
               context.Jobs.AddObject(myEntity);
           }
    
           context.SaveChanges();
           return job;
       }
    }
    

    【讨论】:

    • 但是它给出了这个错误:无法创建抽象类或接口'test.Repositories.IRepository'的实例
    • 你需要实现IRepository。我将使用示例实现来更新我的答案。传入实现,而不是接口。您无法实例化接口,这就是您的第二个错误的含义。
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2013-12-31
    • 2016-12-14
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多