Pergunta

Eu estou trabalhando em uma demo que faz uso da capacidade Spring.NET COI em ASP.NET MVC. É como o tipo de aplicação MyBlog apresentado em par programação vídeo tutorial sobre www.asp.net site. Eu completei a mesma demonstração usando a estrutura Unidade da Microsoft e agora quer experimentar o container Spring. Para esse fim Eu tenho implementado um IControllerFactory simples que primeiro cria a fábrica de objeto Primavera assim:

IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))

e ao lado fica o controlador daquela fábrica assim:

public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
    IController result = context.GetObject(controllerName) as IController;
    return result;
}

(manipulação de erro despojado para fins de simplificação).

Agora, em algum lugar na minha HomeController eu tenho esse tipo de ação:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddEntry([Bind] BlogEntry entry, int id) {
    entry.EntryDate = DateTime.Now;
....

E aqui está a parte de vista AddEntry.aspx que define os editores para o parâmetro de entrada (coisas realmente básico):

<form method="post" action="/Home/AddEntry/<%= ViewData["id"] %>">
    <table>
        <tr>
            <td><label for="Title">Title</label></td>
            <td><input name="entry.Title" type="text"/></td>
        </tr>
        <tr>
            <td><label for="Text">Content</label></td>
            <td><input name="entry.Text" type="text"/></td>
        </tr>
    </table>
    <br />
    <input type="submit" value="Add entry" />
    <input type="button" value="Cancel" onclick="history.back(-1);" />
</form>

Agora, aqui está o negócio: Quando eu estou usando a Unidade IoC ele funciona como um encanto. parâmetro "entrada" fica desserializado a partir de minha forma como deveria e a linha

entry.EntryDate = DateTime.Now; 

concluída sem problemas.

No entanto, quando eu mudar para Spring.NET fábrica de objeto (como descrito acima) as coisas começam a ir nozes. Primeiro de todos os parâmetros voltas "entrada" nulo assim uma exceção é lançada. Para rastrear o possível problema no meu fim Eu tenho implementado um tipo de IModelBinder personalizado que se parece com isso:

public class BlogEntryBinder : IModelBinder {
    public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
        ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
        return result;
    }
}

Quando eu vim aqui usando a estrutura Unidade e detalhar bindingContext para HttpRequest vejo que o Request.HttpMethod é "POST" e Request.Form está devidamente preenchido. Quando eu fazer o mesmo usando Spring.NET o método é "GET" e Request.Form está vazio. Quando passo no entanto I à minha ação do controlador (addEntry) e detalhar o pedido em ambas as situações que eu vejo que o Request.HttpMethod e Request.Form têm seus valores apropriados.

Agora, a questão é como faço para corrigir a versão com Spring.NET para que ele funciona exatamente como a que utiliza estrutura Unidade?

Foi útil?

Solução

Eu encontrei a resposta!

A minha definição de objeto parecia que:

<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
    <property name="BlogService" ref="BlogService" />
    <property name="BlogEntryService" ref="BlogEntryService" />
    <property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>

Nevermind as propriedades sendo definido o que ele realmente faz é ele retorna a mesma instância cada vez que eu pedir para este objeto usando

IController result = context.GetObject(controllerName) as IController;

Então, quando eu mudei a definição de

<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController" singleton="false">
    <property name="BlogService" ref="BlogService" />
    <property name="BlogEntryService" ref="BlogEntryService" />
    <property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>

tudo começou a trabalhar muito bem.

Com os melhores cumprimentos, Matthias.

Outras dicas

apenas uma nota adicional para esclarecer este comportamento: Controladores são tratados como protótipos pelo quadro ASP.NET MVC, mas o padrão de Primavera para o modo de Singleton. Portanto, você precisa marcar explicitamente o objeto como não-singleton na configuração recipiente. O próximo módulo de integração Spring MVC vai cuidar do presente, assim você não vai executar para esse então.

hth, Erich

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top