2016-02-11 2 views
2

Я разработать веб-приложение, и мой доступ к данным с помощью Entity Framework 6 кода первогоAutofac Родовых фабрики

У меня есть эта зависимость в моем DataService слое:

public DataService(IRepository<Folder> folders, IRepository<Letter> letters, IRepository<Destination> destinations) 

в тех depebdencies я инъекционная следующие тип отдельно :

FoldersRepository,

LettersRepository,

Направления Репозитарий

Мне нужны эти репозитории по запросу. Есть ли способ внедрить их с Autofac лучше, чем один за другим (для случая я добавлю больше хранилищ и будущее)

Мне не нужна ссылка с моего DAL на Autofac.

EDIT: Это то, что я хочу иметь:

public IRepository<T> where T: BaseEntityObject 
{ 
    void Add(T entity); 

    void Remove(T entity); 

    List<T> Get(); 

    T FindById(int id); 

    int SaveChanges(); 

    void Dispose(); 

} 


public abstract class EFRepository<T> : IRepository<T> 
{ 
    protected readonly DbContext Context; 

    public EFRepository(DbContext context) 
    { 
     Context = context; 
    } 

    public abstract List<T> Get(); 

    public void Add(T item) 
    { 
     Context.Set<T>().Add(item); 
    } 

    public void Remove(T item) 
    { 
     Context.Set<T>().Remove(item); 
    } 

    public void Update(T item) 
    { 
     Context.Entry(item).State = EntityState.Modified; 
    } 

    public void Dispose() 
    { 
     Context.Dispose(); 
    } 

    public int SaveChanges() 
    { 
     return Context.SaveChanges(); 
    } 

    public T FindById(int id) 
    { 
     return Context.Set<T>().Find(id); 
    } 
} 


public LettersRepository : EFRepository<Letter> 
{ 
    public LettersRepository(DbContext context) : base(context) {} 

    // Override for case includes will be needed in future 
    public override List<T> Get() 
    { 
     return Context.Set<T>().ToList(); 
    } 
} 

public FoldersRepository : EFRepository<Folder> 
{ 
    public FoldersRepository(DbContext context) : base(context) {} 

    public override List<T> Get() 
    { 
     return Context.Set<T>().Include("Letters").ToList(); 
    } 
} 


public class DataService 
{ 
    private IRepositoriesFactory _repositoriesFactory; 

    public DataService(IRepositoriesFactory repositoriesFactory) 
    { 
     _repositoriesFactory = repositoriesFactory; 
    } 

    public bool AddFolder(Folder folder) 
    { 
     var isAdded = false; 

     using (var foldersRepository = _repositoriesFactory.Create<FoldersRepository>) 
     { 
      if (foldersRepository.Add(folder)) 
      { 
       foldersRepository.SaveChanges(); 
       isAdded = true; 
      } 
      else 
      { 
       Log("folder couldn't be addded"); 
      } 
     } 

     return isAdded; 
    } 
} 

    public bool AddLetter(Letter letter) 
    { 
     var isAdded = false; 

     using (var lettersRepository = _repositoriesFactory.Create<LettersRepository>) 
     { 
      if (lettersRepositoryv.Add(folder)) 
      { 
       lettersRepository.SaveChanges(); 
       isAdded = true; 
      } 
      else 
      { 
       Log("letter couldn't be addded"); 
      } 
     } 

     return isAdded; 
    } 

    // More methods that manipulates data... 
} 

// This layer is not in my DAL project (the one using EF), Data service is the API supplier for DAL 
public class DataAccessLayer 
{ 
    private IDataService _dataService 

    public DataAccessLayer(IDataService dataService) 
    { 
     _dataService = dataService 
    } 

    public void HandleAddFolderRequest(AddFolderRequestMessage msg) 
    { 
     if (!_dataService.AddFolder(msg.Folder)) 
     { 
      Log ("Adding folder failed"); 
      Broadcast(new AddFolderResponseMessage()); 
      return; 
     } 

     Log("Adding folder succeeded"); 
     Broadcast(new AddFolderResponseMessage(true));  
    } 

    public void HandleAddLetterRequest(AddLetterRequestMessage msg) 
    { 
     if (!_dataService.AddLetter(msg.letter)) 
     { 
      Log ("Adding letter failed"); 
      Broadcast(new AddLetterResponseMessage()); 
      return; 
     } 

     Log("Adding letter succeeded"); 
     Broadcast(new AddLetterResponseMessage(true));  
    } 

    public void HandleGetAllFolderLetters(GetFolderRequestMessage msg) 
    { 
     var letters = _dataService.GetFolderLetters(msg.FolderId); 

     if (letters == null) 
     { 
      Log ("Could not get the folder's letters"); 
      Broadcast(new GetFolderResponseMessage()); 
      return; 
     } 

     Log("Got the folder's letters successfull"); 
     Broadcast(new GetFolderResponseMessage(true));  
    } 

    // And so on.. more data manipulatation handling methods 
} 


// The Part I dont know how and where to implement 

public interface IRepositoriesFactory 
{ 
    T Create<T>() where T : class 
} 

public class RepositoriesFactory : IRepositoriesFactory 
{ 
    public T Create<T>() where T : class 
    { 
     // THE MAGIC HAPPENS HERE 
    } 
} 
+0

Привет, я думаю, цитата «Каковы плюсы и минусы использования Autofac в xml configuratuon вместо кода?» должен быть отдельный вопрос. – Seabizkit

+0

Вернуться к исходному вопросу ... Я думаю, что его трудно сказать без контекста ... кода.Я привык видеть инъекцию в контроллер ... но не на уровне обслуживания. Я не верю, что это будет так. Им нужно будет вводить один за другим ... говоря, что ... вы не даете одной услуге * на большую ответственность ... и предпочтете сосредоточиться на этом как на корне для беспокойства. – Seabizkit

+0

Согласовано о конфигурации. Я отредактировал и поместил большую часть кода, надеюсь, что вы или кто-нибудь может помочь –

ответ

1

Это может служить иллюстрацией и не может быть связано с ответом на вопрос.

Предполагая, что это веб-проекта MVC:

Вы бы контроллер.

HomeController например

Допустим, что HomeContoller отвечает за приборную панель и показал вам все виды сочных информации.

Так нам нужны данные ....

class HomeContoller 
{ 
    ServiceClass1 _serviceClass1 
    public HomeContoller(ServiceClass1 serviceClass1) 
    { 
     _serviceClass1 = serviceClass1; 
    } 

    public ActionResult Index() 
    { 
     var data = _serviceClass1.GetFancyData(); 
     return View(data); 
    } 


} 

Это основа вы можете сделать это более или менее сложным ... то есть, как вы ваш случай, вы хотите сделать это на вашем уровне услуг. На данный момент я понятия не имею, если это хорошая идея или нет .... но, читая комментировать, я не думаю, что это так.

В любом случае, здесь нужно попытаться показать вам, что нет смысла создавать и использовать экземпляр с использованием кода типа DI в вашем DataService.

Я расскажу об этом, следуя этим вопросам.

Обновление Пример !!!

public class FolderService 
{ 
    private IFoldersRepository _foldersRepository; 

    public FolderService(IFoldersRepository foldersRepository) 
    { 
     _foldersRepository = foldersRepository; 
    } 

    public bool SaveFolder(Folder folder) 
    { 
     if (folder == null) 
      return false; 

     if (folder.Id == 0) 
     { 
      folder.CreateOnDate = DateTime.Now; 
      _foldersRepository.Folders.Add(folder); 
     } 

     //change this to cast the SaveChanges to bool 
     // also not so sure this is a gd idea... bt thats by the by for this.... 
     //--------------------- 
     try 
     { 
      _foldersRepository.SaveChanges(); 
      return true; 
     } 
     catch(exception ex) 
     { 
      return false; 
     } 
     //--------------------- 
    } 
} 
+0

Прежде всего, спасибо большое! Что касается вашего обновления, я не понял разницу между сохранением контекста в вашем коде и тем, что я опубликовал, я ошибаюсь? Откуда возникает Контекст? Контекст сохраняется внутри репозитория –

+0

Простите, что вы на 100% правильны, я не закончил свой пример ..... ха-ха совершенно прав, где, черт возьми, появился «Conetxt», но я думаю, что вы получите его сейчас быть из _foldersRepository ... Ill update, чтобы правильно отражать. Но опять-таки много кода вроде бы пропало, я просто пытался показать ... как бы это выглядело. Исправленные вещи, дайте мне знать, если есть больше ошибок, сосис скопировал это из одного из моих собственных проектов и, похоже, пропустил несколько изменений. – Seabizkit

+0

Хорошо, спасибо, что прогуливаетесь со мной весь этот путь! –

0

Прежде всего, вам нужно просто установить autofac к вашему проекту драйвера (вверху), и вы должны зарегистрировать свои классы там. Все другие проекты должны использовать интерфейсы.

Затем вы можете использовать общую регистрацию.

builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope(); 
Смежные вопросы