В настоящее время я создаю свое первое приложение MVC 3, используя EF Code First, SQL CE и Ninject.
Я много читал об использовании репозиториев, единиц работы и уровней обслуживания. Я думаю, что я разобрался с основами, и я сделал свою собственную реализацию.
Это мои текущие настройки:
Сущность
public class Entity
{
public DateTime CreatedDate { get; set; }
public Entity()
{
CreatedDate = DateTime.Now;
}
}
public class Profile : Entity
{
[Key]
public Guid UserId { get; set; }
public string ProfileName { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
public Profile()
{
Photos = new List<Photo>();
}
public class Photo : Entity
{
[Key]
public int Id { get; set; }
public Guid FileName { get; set; }
public string Description { get; set; }
public virtual Profile Profile { get; set; }
public Photo()
{
FileName = Guid.NewGuid();
}
}
SiteContext
public class SiteContext : DbContext
{
public DbSet<Profile> Profiles { get; set; }
public DbSet<Photo> Photos { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Интерфейс: IServices
public interface IServices : IDisposable
{
PhotoService PhotoService { get; }
ProfileService ProfileService { get; }
void Save();
}
Реализация: Услуги
public class Services : IServices, IDisposable
{
private SiteContext _context = new SiteContext();
private PhotoService _photoService;
private ProfileService _profileService;
public PhotoService PhotoService
{
get
{
if (_photoService == null)
_photoService = new PhotoService(_context);
return _photoService;
}
}
public ProfileService ProfileService
{
get
{
if (_profileService == null)
_profileService = new ProfileService(_context);
return _profileService;
}
}
public void Save()
{
_context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Интерфейс
public interface IPhotoService
{
IQueryable<Photo> GetAll { get; }
Photo GetById(int photoId);
Guid AddPhoto(Guid profileId);
}
Осуществление
public class PhotoService : IPhotoService
{
private SiteContext _siteContext;
public PhotoService(SiteContext siteContext)
{
_siteContext = siteContext;
}
public IQueryable<Photo> GetAll
{
get
{
return _siteContext.Photos;
}
}
public Photo GetById(int photoId)
{
return _siteContext.Photos.FirstOrDefault(p => p.Id == photoId);
}
public Guid AddPhoto(Guid profileId)
{
Photo photo = new Photo();
Profile profile = _siteContext.Profiles.FirstOrDefault(p => p.UserId == profileId);
photo.Profile = profile;
_siteContext.Photos.Add(photo);
return photo.FileName;
}
}
Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
Database.SetInitializer<SiteContext>(new SiteInitializer());
}
NinjectControllerFactory
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings()
{
ninjectKernel.Bind<IServices>().To<Services>();
}
}
PhotoController
public class PhotoController : Controller
{
private IServices _services;
public PhotoController(IServices services)
{
_services = services;
}
public ActionResult Show(int photoId)
{
Photo photo = _services.PhotoService.GetById(photoId);
if (photo != null)
{
string currentProfile = "Profile1";
_services.PhotoService.AddHit(photo, currentProfile);
_services.Save();
return View(photo);
}
else
{
// Add error message to layout
TempData["message"] = "Photo not found!";
return RedirectToAction("List");
}
}
protected override void Dispose(bool disposing)
{
_services.Dispose();
base.Dispose(disposing);
}
}
Я могу построить свое решение, и, похоже, оно работает правильно.
Мои вопросы:
- Есть ли какие-либо очевидные недостатки в моей реализации, которые я пропускаю?
- Смогу ли я использовать это с TDD? Обычно я вижу издевательства над репозиториями, но я не использовал это в приведенном выше, это вызовет проблемы?
- Правильно ли я использую DI (Ninject)?
Я программист-хобби, поэтому любые комментарии и / или предложения к моему коду приветствуются!