Pergunta

Na sequência da minha pergunta recente sobre Objetos grandes e complexos como resultado de um serviço da Web.Tenho pensado em como posso garantir que todas as futuras classes filhas sejam serializáveis ​​para XML.

Agora, obviamente eu poderia implementar o IXmlSerializável interface e, em seguida, colocar um leitor/gravador nela, mas eu gostaria de evitar isso, pois isso significa que preciso instanciar um leitor/gravador sempre que quiser, e 99,99% do tempo estarei trabalhando com um corda então posso simplesmente escrever o meu próprio.

Entretanto, para serializar para XML, estou simplesmente decorando a classe e seus membros com o XML??? atributos ( XmlRoot , Elemento XML etc.) e depois passá-lo para o XMLSerializador e um StringWriter para obter a corda.O que é tudo de bom.Pretendo colocar o método para retornar a string em um método utilitário genérico para não precisar me preocupar com tipo etc.

O que me preocupa é o seguinte:Se eu não decorar a(s) classe(s) com os atributos necessários, um erro não será gerado até o tempo de execução.

Existe alguma maneira de impor a decoração de atributos?Isso pode ser feito com FxCop? (Ainda não usei o FxCop)

ATUALIZAR:

Desculpe pela demora em fechar isso pessoal, há muito o que fazer!

Definitivamente gosto da ideia de usar reflexão para fazer isso em um caso de teste, em vez de recorrer ao FxCop (gostaria de manter tudo junto). A resposta de Fredrik Kalseth foi fantástico, obrigado por incluir o código, pois provavelmente teria levado um pouco de pesquisa para descobrir como fazer isso sozinho!

+1 para os outros caras para sugestões semelhantes :)

Foi útil?

Solução

Eu escreveria um teste de unidade/integração que verifica se qualquer classe que corresponda a alguns critérios (ou seja, subclasse X) está decorada adequadamente.Se você configurar sua compilação para ser executada com testes, poderá fazer com que a compilação falhe quando esse teste falhar.

ATUALIZAR:Você disse: "Parece que terei que arregaçar as mangas e garantir que os testes unitários sejam mantidos coletivamente" - você não precisa.Basta escrever uma classe de teste geral que use reflexão para encontrar todas as classes que precisam ser afirmadas.Algo assim:

[TestClass]
public class When_type_inherits_MyObject
{
    private readonly List<Type> _types = new List<Type>();

    public When_type_inherits_MyObject()
    {
        // lets find all types that inherit from MyObject, directly or indirectly
        foreach(Type type in typeof(MyObject).Assembly.GetTypes())
        {
            if(type.IsClass && typeof(MyObject).IsAssignableFrom(type))
            {
                _types.Add(type);
            }
        }
    }

    [TestMethod]
    public void Properties_have_XmlElement_attribute
    {
        foreach(Type type in _types)
        {
            foreach(PropertyInfo property in type.GetProperties())
            {
                object[] attribs = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
                Assert.IsTrue(attribs.Count > 0, "Missing XmlElementAttribute on property " + property.Name + " in type " + type.FullName);
            }
        }
    }
}

Outras dicas

Você pode escrever testes de unidade para verificar esse tipo de coisa - basicamente usa reflexão.

Dado que isso é possível, acho que também seria possível escrever uma regra FxCop, mas nunca fiz tal coisa.

Você pode escrever uma regra FxCop ou até mesmo verificar os atributos chamando GetType() no construtor da classe base e refletindo sobre o tipo retornado.

Uma boa regra FXCop (e que estou achando que preciso agora) seria verificar se todos os objetos que estão sendo adicionados à sessão ASP.NET possuem o atributo Serializable.Estou tentando passar do estado da sessão InProc para o SQL Server.A primeira vez que solicitei uma página, meu site explodiu porque objetos não serializáveis ​​estavam sendo armazenados na Sessão.Então veio a tarefa de vasculhar todo o código-fonte procurando cada instância onde um objeto está definido na Sessão...FXCop seria uma boa solução.Algo para trabalhar...

Você também pode usar este conceito/pós-processador para impor relacionamentos entre atributos e usar login semelhante para impor relacionamentos entre classes e atributos em tempo de compilação:

http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92

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