none
Usando ref com uma propriedade de classe? RRS feed

  • Pergunta

  • Bom dia pessoal.

    Estou em um projeto onde temos classes DAO para cada tabela. Que são usadas pelas classes de negócio em conjunto com BancoDadosSLQ para fazer gravar nas tabelas. Como indicado a seguir...

    public class UsuarioDao : IUsuarioDao
    {
        public IBcoDados Conexao { get; set; }
        public UsuarioDao(IBcoDados conexao)
        {
            Conexao = conexao;
        }
        public bool ExcluirRegPorId(int id)
        {
            //Define a consulta para executar uma procedure
    	Conexao.TipoComando(CommandType.StoredProcedure);
    	Conexao.SetaComando("USUARIOSExcluirRegporId");
            Conexao.AdicionaParametro("@ID", Id);
            //Aplica a atualização na tabela do banco
            Conexao.ExecutaSemQuery();
            return true;
        }
        public bool IncluirRegistro()
        {...}
        etc
    }
    
    public class Usuario : IUsuario
    {
        public BcoDados Banco { get; set; }
        public Usuario()
        {
            Banco = new AbreBcoDados();
            etc...
        }
        public bool ApagaUsuario()
        {
            //Abre Conexao
            Banco.AbreBancoDados();
            //Referencia classes utilizadas
            UsuarioDao = new UsuarioDao(Banco);
    
            //EXECUTA DELETE
            UsuarioDao.ExcluirRegPorId(UsuarioEnt.Id));
    
            Banco.FechaBancoDados();
            return true;
        }
        etc...
    }

    Isso está funcionando belezinha!

    Só que nosso analista veio dizer agora que a conexão tem que ser compartilhada por várias classes DAO (Usuario, Pessoa, Sessao e por aí vai). E que para isso ele deve ser do tipo ref ou seja pediu pra fazer a seguinte mudança...

    public class UsuarioDao : IUsuarioDao
    {
        public IBcoDados Conexao { get; set; }
        public UsuarioDao(ref IBcoDados conexao)
        {
            Conexao = conexao;
        }
        ...
    }

    Aí minha chamada passaria a ser 

    UsuarioDao = new UsuarioDao(ref Banco);

    Mas como podem ver no código Banco é uma propriedade da classe Usuario. Aí o Visual Studio me retorna que "A property or indexer may not be passed as an ou or ref parameter."

    E eu não sei como resolver isso. Preciso da propriedade... Será que além dela vou ter que criar uma variável local em cada método da classe usuário?

    public class Usuario : IUsuario
    {
        public BcoDados Banco { get; set; }
        public Usuario()
        {
            Banco = new AbreBcoDados();
            etc...
        }
        public bool ApagaUsuario()
        {
            //Abre Conexao
            IAbreBcoDados BancoParaRef = Banco; //<-------
            BancoParaRef.AbreBancoDados();
            //Referencia classes utilizadas
            UsuarioDao = new UsuarioDao(ref BancoParaRef);
    
            //EXECUTA DELETE
            UsuarioDao.ExcluirRegPorId(UsuarioEnt.Id));
            ...
    Alguém tem alguma sugestão melhor?

    terça-feira, 18 de abril de 2017 12:21

Respostas

  • Mas se a conexão será compartilhada, acredito que o mais indicado seja criar o objeto fora da classe Usuario também, ficando:

    public class ClasseQueConsomeUsuario
    {
       IBcoDados _banco;
    
       public ClasseQueConsomeUsuario()
       {
           _banco = new AbreBcoDados();
    
           Usuario usuario = new Usuario(ref _banco);
       }
    }
    
    public class Usuario : IUsuario
    {
        IBcoDados _banco;
    
        public IBcoDados Banco { get { return _banco; } }
    
        public Usuario(ref IBcoDados banco)
        {
            _banco = banco;
    
            UsuarioDao dao = new UsuarioDao(ref _banco);
        }
    }


    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, remember to "Mark as Answer".

    Se achou este post útil, por favor clique em "Votar como útil". Se por acaso respondeu sua dúvida, lembre de "Marcar como Resposta".

    terça-feira, 18 de abril de 2017 12:44

Todas as Respostas

  • Mas se a conexão será compartilhada, acredito que o mais indicado seja criar o objeto fora da classe Usuario também, ficando:

    public class ClasseQueConsomeUsuario
    {
       IBcoDados _banco;
    
       public ClasseQueConsomeUsuario()
       {
           _banco = new AbreBcoDados();
    
           Usuario usuario = new Usuario(ref _banco);
       }
    }
    
    public class Usuario : IUsuario
    {
        IBcoDados _banco;
    
        public IBcoDados Banco { get { return _banco; } }
    
        public Usuario(ref IBcoDados banco)
        {
            _banco = banco;
    
            UsuarioDao dao = new UsuarioDao(ref _banco);
        }
    }


    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, remember to "Mark as Answer".

    Se achou este post útil, por favor clique em "Votar como útil". Se por acaso respondeu sua dúvida, lembre de "Marcar como Resposta".

    terça-feira, 18 de abril de 2017 12:44
  • Também pensei isso. É a mesma lógica de uma variável Global no VB, né?Sabe, aqui ainda estamos em faze de prototipagem do sistema, que será web, mas só para testes crio algumas forms, pq não temos nenhuma tela/página.

    E  não consegui convencer meu Analista(chefe) dessa idéia. Ele argumentou: "Vc esta esquecendo que não vamos utilizar forms, e a Variável global terá que ficar em cada página web... Não tem como..."

    Então se alguém mais tiver outra idéia.

    terça-feira, 18 de abril de 2017 13:15
  • No caso da web o funcionamento é bem diferente, logo eu não faria uma prova de conceito utilizando uma plataforma diferente. A variável de conexão com o banco precisa ser criada novamente a cada página ou operação que o usuário realiza. Você pode compartilhar ela entre os objetos, mas apenas no mesmo request/fluxo.


    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, remember to "Mark as Answer".

    Se achou este post útil, por favor clique em "Votar como útil". Se por acaso respondeu sua dúvida, lembre de "Marcar como Resposta".

    terça-feira, 18 de abril de 2017 14:01