با سلام
من فکر میکنم این شیوه آموزش که در این تاپیک داره استفاده میشه خیلی مناسب نباشه.
من خودم برای دنبال کردن این که تا الان چه نتیجه ای گرفتیم واقعا حوصله ام سر رفت.
@jaykob:
یک مثال میزنم امیدوارم مفید واقع بشه.
در نظر داشته باشید که قراره عملیات CRUD بر روی یک سری اطلاعات انجام بشه و از قبل مشخص نیست که این نوع اطلاعات قراره در چه جایی ذخیره بشن(پایگاه داده،فایل سیستم) و حتی مشخص نیست که قراره چه بیزینس هایی روی این اطلاعات اعمال بشن.
ما از قبل نمیدونیم و یا احتمال این رو میدیم که در آینده تغییراتی داشته باشیم(مثلا تغییر پایگاه داده)
برای این کار میایم Interface هایی رو تولید میکنیم که مشخص کنه چه کارهایی باید انجام بشه.
کلاس های مربوطه رو که از اینترفیس ها ارث برده پیاده میکنیم تا چگونگی اجرای یک فرِآیند رو پیاده کنه.(این کلاس میتونه در یک پروژه خارج از پروژه اصلی باشه)
حالا بحث اینه که اگه برای استفاده از کلاس مربوطه بیایم یه Instance از اون کلاس رو مستقیما ایجاد بکنیم وابستگی داریم به همون کلاسی که ازش Instance گرفتیم و میخواهیم این وابستگی رو از طریق تزریق وابستگی و انتخاب و ایجاد کلاس در Run Time از بین ببریم.
فکر کنم توضیحات خیلی کامل تر و بهتر از توضیحات من رو قبلا مطالعه کردید. مثلا واقعا میزنم. (خود من از کد نگاه کردن خیلی سریع تر یاد میگیرم)
namespace DependencyInjection.Models
{
public class BaseEntity
{
}
public class Person : BaseEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
کنترلر:
namespace DependencyInjection.Controllers
{
public class PersonController : BaseController<Person>
{
public PersonController(IService<Person> service) : base(service) { }
}
}
namespace DependencyInjection.Controllers
{
public class BaseController<T> : Controller where T : BaseEntity
{
protected IService<T> Service;
public BaseController(IService<T> service)
{
this.Service = service;
}
public ActionResult Index()
{
return View(Service.All);
}
public ActionResult Insert(T entity)
{
Service.Insert(entity);
return View(); // show custom result
}
public ActionResult Update(T entity)
{
Service.Update(entity);
return View(); // show custom result
}
public ActionResult Delete(T entity)
{
Service.Delete(entity);
return View(); // show custom result
}
}
}
سرویس:
namespace DependencyInjection.Services
{
public interface IService<T> : IDisposable where T : BaseEntity
{
IQueryable<T> All { get; }
T Find(params object[] keys);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
}
}
ریپازیتوری:
namespace DependencyInjection.Repositories
{
public interface IRepository<T> : IDisposable where T : BaseEntity
{
IQueryable<T> All { get; }
T Find(params object[] keys);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
}
}
دیتا:
namespace DependencyInjection.Data
{
public class DependencyInjectionDbContext : DbContext
{
public DependencyInjectionDbContext() : base("DefaultConnection") { }
public DbSet<Person> Persons { get; set; }
}
}
پیاده سازی ها :
namespace DependencyInjection.Services
{
public class BaseService<T> : IService<T> where T : BaseEntity
{
protected IRepository<T> repo;
public BaseService(IRepository<T> repo)
{
this.repo = repo;
}
public virtual IQueryable<T> All
{
get { return repo.All; }
}
public virtual T Find(params object[] keys)
{
return repo.Find(keys);
}
public virtual void Insert(T entity)
{
repo.Insert(entity);
}
public virtual void Update(T entity)
{
repo.Update(entity);
}
public virtual void Delete(T entity)
{
repo.Delete(entity);
}
public void Dispose()
{
repo.Dispose();
}
}
}
namespace DependencyInjection.Repositories
{
public class BaseRepository<T> : IRepository<T> where T : BaseEntity
{
protected readonly DbContext context;
public BaseRepository(DbContext contextFactory)
{
context = contextFactory;
}
public IQueryable<T> All
{
get { return context.Set<T>(); }
}
public T Find(params object[] keys)
{
return context.Set<T>().Find(keys);
}
public void Insert(T entity)
{
context.Set<T>().Add(entity);
context.SaveChanges();
}
public void Update(T entity)
{
context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
}
public void Delete(T entity)
{
context.Entry(entity).State = System.Data.Entity.EntityState.Deleted;
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
}
درواقع کد زیر رو بوسیله تزریق وابستگی ایجاد میکنیم:
namespace DependencyInjection.Controllers
{
public class PersonController : BaseController<Person>
{
public PersonController() : this(new BaseService<Person>(new BaseRepository<Person>(new DependencyInjectionDbContext()))) { }
}
}