EF N-Tier Architecture [closed]

浪尽此生 提交于 2019-12-04 12:42:01

First of all DO NOT!!! share your DAL over multiple platform. Share your BL which uses DAL. As long as your BL represent solutions to your application requirements you do not need to expose your DAL and, please don't. Also exposing DAL has the disadvantage of exposing more vulnerabiilties to hackers and direct acces to DAL provides a btpass mechanism to your Business Logic, Controls and Validations in your BL.

Answer 1: Possibly but not need to. Thinking with SOA in mind I suggest to use DTOs. Either they are entities or more complex, composite classes of several and/or partial entities. If you use entities this gives you more flexibility to provide information via BL (you can send several portions of data at once by one method call) and hides youe entity (also DB structure) from third party users providing a better sense of security.

Answer 2: Again, thinking with SOA in mind, do not construct your BL/Service methods according to your User Interface. BL (as the name implies) provides data according to "how the work is done" not "how the work is done by the user on the screen". And if you try to manage your data from GUI you will also start to violate N-tier architecture. DO NOT!!! use any data spesific class and/or methods outside of DAL. This will be the true use of layering.

Regards.

RePierre

You need to use Unit of Work and Repository patterns with a Dependency Injection framework like StructureMap or Unity.

Basically, what you need to do is to create interfaces:

public interface IUnitOfWork
{
    void SaveChanges();
}

public interface IRepository<TItem>
{
    TItem GetByKey<TKey>();

    IQueryable<TItem> Query();
}

Now, in your DbContext class implement the interfaces above and somewhere in your Business Layer register the implementation of the interfaces:

public void RegisterDependencies(Container container)
{
    // Container is a Structure Map container.
    container.ForRequestedType<IUnitOfWork>()
        .CacheBy(InstanceScope.HttpContext)
        .TheDefaultConcreteType<DbContext>();    
}

See StructureMap Scoping Docs on how to configure the scope of an instance.

Now, with all that code in place, each of your Business Layer class that needs to perform some data operations would look like this:

public class SomeService
{
    public SomeService(IRepository<SomeItem> repository, IUnitOfWork unitOfWork)
    {
        this.repository = repository;
        this.unitOfWork = unitOfWork;
    }

    public void MarkItemCompleted(int itemId)
    {
        var item = repository.GetByKey(itemId);
        if(item != null)
        {
            item.Completed = true;
            unitOfWork.SaveChanges();
        }
    }
}

Now, hide the creation of services behind a factory:

public class ServiceFactory
{
    private readonly Container container;// = initialize the container

    public TService CreateService<TService>()
    {
        return container.GetInstance<TService>();
    }
}

And in your GUI layer call only methods of service classes created through ServiceFactory; if your GUI is an ASP.NET MVC project you don't need to create the ServiceFactory class - you can derive from DefaultControllerFactory and override GetControllerInstance method. See the answer here for an example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!