2010-07-19 3 views
2

큰 편집 :이 문제는 아마도 MEF가 원인 일 수 있습니다!Entity Framework 자체 추적 엔터티 및 ASP MVC .NET 및 Managed Extensibility Framework와 관련된 문제

저는 서비스 지향 아키텍처를 사용하고 있으며 모든 MVC 컨트롤러가 서비스를 통해 작업을 수행하도록하고 있습니다.

public abstract class BaseService 
{  
    protected MyObjectModel context; 

    public BaseService() 
    { 
      context = new MyObjectModel(); 
    } 
} 

그때 나는 또한 모든 액세스를 제공하는 기본 클래스에서 상속 내 컨트롤러가

[Export(typeof(IEmployeeService))]  
public class EmployeeService : BaseService, IEmployeeService 
    { 
     public void NewEmployee(Employee newEmployee) 
     { 
       context.Employees.AddObject(newEmployee); 
       context.SaveChanges(); 
     } 
    } 

을 상속 서비스가 :

나는 다음과 같습니다 기본 서비스를 필요한 서비스가있어 전화 할 수 있습니다.

EmployeeService.AddEmployee(new Employee() { Name = "JohnDoe"}); 

ObjectContext가 생성시 데이터베이스를 정확하게 반영하지 못했음을 알기 전까지

BaseService 생성자에 중단 점을 넣고 Sql Server의 프로필러를 사용하여 새로운 MyObjectModel이 DB를 치지 않고 일부 캐시에서 데이터를 가져 오는 것을 보았습니까?

컨텍스트에서 컬렉션의 MergeOption 속성을 발견하고 데이터를 새로 고쳤습니다.하지만 이제는 엔터티를 반환하는 새 서비스 메서드를 만들 때마다 사용해야합니다.

편집 : 내 문제가 MEF에 의해 발생한 것임을 알 때까지 나는 걸림돌을 겪었습니다.

기본 ControllerFactory를 재정의하고 서비스를 인스턴스화하기 위해 MEF를 사용하는 컨트롤러를 구현했습니다. 내가보고있는 것은 MEF 호출간에 개체를 유지하는 것입니다.

그래서

1) 어디에서 더이 문제에 읽을 수 있습니까? 그리고 객체를 호출 할 때마다 멈추고 새로운 컴포지션을 강제로 수행하려면 어떻게해야합니까?

감사합니다.

답변

1

나는이 문제를 결국 내 머리카락을 뽑은 지 몇 시간 만에 해결했다.

내 ControllerFactory 구현은 다음과 같습니다.

public class ControllerFactory : IControllerFactory 
    { 
     CompositionContainer container; 
     DefaultControllerFactory controllerFactory; 

     public ControllerFactory() 
     { 
      container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
      controllerFactory = new DefaultControllerFactory(); 
     } 

     public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) 
     { 
      var controller = controllerFactory.CreateController(requestContext, ControllerName); 

      container.ComposeParts(controller); 

      return controller; 
     } 

     public void ReleaseController(IController controller) 
     { 
      var disposable = controller as IDisposable; 
      if (disposable != null) 
      { 
       disposable.Dispose(); 
      } 
     } 
    } 

그리고 응용 프로그램 시작 프로그램에서이 줄을 호출했습니다.

ControllerBuilder.Current.SetControllerFactory(new ControllerFactory()); 

컨트롤러 팩터 리가 AppDomain주기마다 한 번만 초기화되므로 구성 컨테이너도 마찬가지였습니다. 내 서비스 클래스는 Shared 또는 Non Shared 용도로 특별히 표시되지 않았으므로 컨테이너는 각각의 참조를 유지했습니다. ControllerFactory가 매 호출마다 새 컨트롤러를 만들 때마다 데이터 불일치가 발생했던 이전 ObjectContext를 포함하여 마지막 호출에서 계속 보유한 참조로 서비스 속성을 채 웁니다.

내 전체 문제는 새로운 버전마다 시행하는 각각의 서비스에

[PartCreationPolicy(CreationPolicy.NonShared)] 

을 추가함으로써 해결되었다.

이제 ObjectContext가 유지해야 할 작은 것이 아니기 때문에 MEF가 여전히 참조를 보유하고 있는지 궁금해합니다. 이 일이 일어나기를 기다리는 메모리 누수가 있습니까?

+0

각 요청마다 별도의 CompositionContainer를 만드는 것이 좋습니다. 그렇다면 MEF가 참조를 유지하는 것에 대해 걱정할 필요가 없습니다 (부품이 IDisposable을 구현하는 경우). 카탈로그를 한 번 만든 다음 각 요청에 대해 해당 카탈로그를 사용하여 CompositionContainer를 만들 수 있습니다. –

+0

각 요청에서 CompositionContainer를 만드는 데 드는 비용은 얼마입니까? 그것들은 무시할 정도로 작습니까? 이런 소리가 올바른 길입니다. –

+0

컨트롤러 팩토리에서 어떤 단계에서이 컨테이너를 만들어야합니까? 요청 당 하나의 ObjectContext를 만들고 서비스간에 공유하려고합니다. 제어기 공장이 그렇게 할 수있는 곳입니까? –

관련 문제