Dependency Injection в C# глазами Java разработчика
Переучиваюсь с Java на C# и возник вопрос, связанный с внедрением зависимостей.
IRepository.cs - мой общий интерфейс для всех Entity-объектов, с которыми я хочу работать из базы данных.
public interface IRepository<T> : IDisposable
where T : class
{
void Create(T entity);
T FindById(long id);
ICollection GetAll();
void Update(T entity);
void Delete(T entity);
void DeleteById(long id);
}
Account.cs - обычный Entity-класс.
[Table("accounts")]
public class Account
{
public Account()
{
}
[Key, Column("id")]
public long Id { get; set; }
[Column("email"), MaxLength(32)]
public string Email { get; set; }
[Column("registration_datetime"), Required]
public DateTime Registration { get; set; }
[Column("last_auth_datetime")]
public DateTime? LastAuth { get; set; }
}
AccountRepository.cs - мой класс с бизнес-логикой.
public class AccountRepository : IRepository<Account>
{
private readonly DatabaseContext _dbContext;
public AccountRepository(DatabaseContext dbContext)
{
_dbContext = dbContext;
}
public void Create(Account entity)
{
_dbContext.Accounts.Add(entity);
}
public Account FindById(long id)
{
return _dbContext.Accounts.Find(id);
}
public ICollection GetAll()
{
return _dbContext.Accounts.ToList();
}
public void Update(Account entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
}
public void Delete(Account entity)
{
_dbContext.Accounts.Remove(entity);
}
public void DeleteById(long id)
{
var tempAccount = FindById(id);
if (tempAccount != null)
{
Delete(tempAccount);
}
}
}
DatabaseContext.cs - класс по настройке EntityFramework Core.
public class DatabaseContext : DbContext {
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
#region Entities
public virtual DbSet<Account> Accounts { get; set; }
#endregion
}
ServerStartHandler.cs - Класс, который автоматически инициализируется во время запуска программы.
public class ServerStartHandler : AsyncResource
{
private readonly ServiceProvider _serviceProvider;
private readonly AccountRepository _accountRepository;
private IConfiguration Configuration { get; }
public ServerStartHandler(AccountRepository accountRepository)
{
_accountRepository = accountRepository;
}
public ServerStartHandler() : base(new ActionTickSchedulerFactory())
{
// read and build configuration
Configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.Build();
// initialize dependency injection
var services = new ServiceCollection();
services.AddEntityFrameworkNpgsql().AddDbContext<DatabaseContext>(options => options
.UseNpgsql(Configuration.GetConnectionString("Database")));
services.AddScoped<IRepository<Account>, AccountRepository>();
// build DI services
_serviceProvider = services.BuildServiceProvider();
}
public override void OnStart()
{
var getAllAccounts = _accountRepository.GetAll();
Console.WriteLine($"Accounts count: {getAllAccounts.Count}");
Console.WriteLine(">> Server started <<");
}
public override void OnStop()
{
Console.WriteLine(">> Server stopped <<");
}
}
Но когда я хочу работать со своим AccountRepository.cs, то он null (как я понял, "инъекция" не прошла).
В Java (в частности, в Spring'е) было проще: просто создать Bean в конфигурационном классе, повесить аннотацию @Autowired, и "полетели". Тут немного сложнее для моего понимания.
Подскажите, может нужно что-то еще добавить? Или где-то я допустил ошибку, что мой объект не виден. Поделитесь любой информацией. Заранее благодарен!
