문제

다음과 같은 인터페이스가 있다고 가정 해 봅시다.

interface IThing {
   int Id { get; set; }
   string Title { get; set; }
}

ASP.NET MVC에는 다음과 같은 컨트롤러 작업에 게시하는 양식이 있습니다.

 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {

    // code to validate and persist the thing can go here            
 }

어디에 단순한 간신히 구현하는 구체적인 클래스입니다 Ithing.

그러나 인터페이스를 다루는 모든 방법을 원합니다. 나는 nhiberate와 그 자체를 사용하는 데이터 어셈블리가 있습니다. Ithing 구현 (그것을 부르자 진짜). "알 수없는 실체"에 대해 불평 할 것이기 때문에 간단한 것을 전달할 수 없습니다.

누구 든지이 작업을 수행하는 더 깨끗한 방법에 대한 아이디어가 있습니까? 나는 공장 수업을 사용하는 선을 따라 무언가에 대해 생각하고있었습니다. 그러나 MVC 양식 바인더를 어떻게 사용할 수 있습니까?

감사!

도움이 되었습니까?

해결책 3

여기에는 몇 가지 좋은 제안이 있었고 실제로 작동하는 솔루션을 생각해 냈습니다. 그러나 나는 무언가로 끝났다. 방금 게시 한 양식 데이터에 대한 모델을 만들었고 기본 모델 바인더를 사용했습니다.

훨씬 간단하고 도메인 모델의 일부가 아닌 데이터를 캡처 할 수 있습니다 (예 : "주석"필드처럼).

다른 팁

사용자 정의를 사용할 수 있습니다 모델 바인더. 그러나 MSDN에 관한 기사는 완전히 쓸모가 없습니다. 검색을 사용하고 더 나은 것을 찾는 것이 좋습니다. 이용 가능한 기사가 있습니다.

나는 이것에 대한 두 가지 접근법을 생각해 냈습니다.

첫 번째는 MVC 컨트롤러에서 사용하는 간단한 PoCo 유형을 번역하기 위해 NHibernate 저장소 클래스에 코드를 추가하는 것이 었습니다.단순한) nhibernate가 원하는 엔티티의 유형에 (진짜):

/// <summary>
/// A NHibernate generic repository.  Provides base of common 
/// methods to retrieve and update data.
/// </summary>
/// <typeparam name="T">The base type to expose 
/// repository methods for.</typeparam>
/// <typeparam name="K">The concrete type used by NHibernate</typeparam>
public class NHRepositoryBase<T, K> 
    : IRepository<T>
    where T : class
    where K : T, new()
{
    // repository methods ...

    /// <summary>
    /// Return T item as a type of K, converting it if necessary
    /// </summary>        
    protected static K GetKnownEntity(T item) {
        if (typeof(T) != typeof(K)) {
            K knownEntity = new K();

            foreach (var prop in typeof(T).GetProperties()) { 
                object value = prop.GetValue(item, null);
                prop.SetValue(knownEntity, value, null);
            }

            return knownEntity;
        } else {

            return (K)item;
        }            
    }

따라서 저장소의 모든 메소드는 getknownentity (t 항목)를 호출 할 수 있으며 전달한 항목의 속성을 nhibernate가 원하는 유형으로 복사합니다. 분명히 이것은 약간 어리석은 느낌이 들었으므로 커스텀 모델 바인더를 살펴 보았습니다.


두 번째 방법에서는 다음과 같은 사용자 정의 모델 바인더를 만들었습니다.

public class FactoryModelBinder<T> 
    : DefaultModelBinder 
    where T : new() 
{

    protected override object CreateModel(ControllerContext controllerContext, 
                                          ModelBindingContext bindingContext, 
                                          Type modelType) {

        return new T();                       
    }

}

그런 다음 global.asax.cs에 다음과 같이 등록했습니다.

ModelBinders.Binders.Add(typeof(IThing), 
            new FactoryModelBinder<RealThing>());

그리고 다음과 같은 것처럼 보이는 컨트롤러 동작으로 잘 작동합니다.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
    // code to process the thing goes here
}

두 번째 접근 방식이 마음에 들지만 대부분의 종속성 주입 작업은 컨트롤러 클래스에 있습니다. Global.asax.cs 에이 모든 Modelbinder Mapping을 추가하고 싶지 않습니다.

이것은 당신의 질문에 방해가되지 않습니다.

우리는 당신이 가진 것과 같은 문제를 다루기 위해 약간 다른 접근법을 사용합니다. 우리의 컨트롤러는 영구 엔티티 필드에 맞는 DTO를 필드별로 받아들입니다. 그런 다음 우리는 사용자입니다 automapper 데이터베이스로 이동할 지속 된 엔티티를 작성합니다. 이렇게하면 Unnessesery 인터페이스를 제거하고 공개 API를 잠그십시오 (Peristance Object의 필드를 바꾸면 클라이언트 코드를 깨뜨리지 않음).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top