Usuário com melhor resposta
Instanciar objeto por string

Pergunta
-
Olá,
começei a escrever essa pergunta aqui e o fórum me sugeriu alguns links. Olhei todos e ainda não estou conseguindo fazer o que quero.
Acho que é simples ... preciso instanciar um objecto de uma classe. Só que o nome da classe precisa vir de uma string.
Exemplo:
Dim className as String = "UsuarioDAO" Dim ob = XXX(className)
E preciso que o 'ob' seja uma instancia da classe UsuarioDAO.
Consegui já chamar funções da mesma classe usando
CallByName(Me, "FuncaoASerChamada", CallType.Method)
mas esse 'Me' precisa ser substituido por outro classe.
Obrigado.
Respostas
-
Uma solução que pegaria bem no seu caso é utilizar o Unity Application Block
Consiste em:
Todas as suas classes implementam uma mesma interface
Ex:
UsuarioDAO: IEntidadeDAO ClienteDAO:IEntidadeDAO
Você cria uma classe mapper que registra todas as suas entidades
myUnityContainer.RegisterType<IEntidadeDAO, UsuarioDAO>("Usuario"); myUnityContainer.RegisterType<IEntidadeDAO, ClienteDAO>("Cliente");
Finalmente, ao invés de fazer o new das suas instâncias, você deixa que container do Unity faça isso pra você:
myUnityContainer.Resolve<IEntidadeDAO>("Usuario");// Retorna instância de UsuarioDAO myUnityContainer.Resolve<IEntidadeDAO>("Cliente");// Retorna instância de ClienteDAO
Gosto dessa técnica pois evita o alto acoplamento e dependências entre as classes.
(Se puder, pesquise mais sobre Injeção de Dependências)
Ou, um jeito mais simples é fazer os news encadeados dentro do seu switch case mesmo.
O problema disso é que pode gerar muitos pontos de manutenção caso as classes sofram alguma alteração, (inclusive afetar os pontos onde você faz o new das instâncias)
Espero ter ajudado
-----------------------------
Tiago Saraiva Ferreira
- Editado Tiago Saraiva Ferreira quinta-feira, 30 de agosto de 2012 04:17
- Marcado como Resposta Harley Araujo quinta-feira, 30 de agosto de 2012 11:19
Todas as Respostas
-
Ola Thiago...
voce pode fazer algo mais ou menos assim:
Dim assembly = Reflection.Assembly.LoadFile("arquivo.dll") Dim instancia = assembly.CreateInstance("namespace.classe") Dim metodo = instancia.GetType().GetMethod("metodo") Dim parametros As Object() = New Object() Dim retorno = metodo.Invoke(instancia, parametros)
- Editado Rui SantosModerator terça-feira, 28 de agosto de 2012 16:45
-
-
Isso nao te ajuda amigo?
var teste = Activator.CreateInstance(Type.GetType("System.String"), new object[] { "value".ToCharArray() });
Se a resposta foi útil por favor qualifique! Janderson Candido de Mattos - MCTS
- Editado Janderson Candido de Mattos terça-feira, 28 de agosto de 2012 17:22
-
Caso a classe esteje no seu assembly em execução vc pode substituir a primeira linha por:
Dim assembly = Reflection.Assembly.GetExecutingAssembly()
Microsoft Community Contributor
Fiz como sugeriu
Dim assembly = Reflection.Assembly.GetExecutingAssembly() Dim instancia = assembly.CreateInstance("UsuarioDAO") Dim metodo = instancia.GetType().GetMethod("funcaoTeste") Dim parametros As Object() = New Object() Dim retorno = metodo.Invoke(instancia, parametros)
Mas aparece o erro :
"Object reference not set to an instance of an object."
minha "funcaoTeste" nao recebe nenhum parametro.
-
Na verdade, o problema mesmo é em instanciar a classe.
Pois já consigo através do
CallByName(instancia, "funcaoTeste", CallType.Method)
chamar uma função. Só que o primeiro parâmetro desse CallByName, é a instancia da classe (que não consegui fazer) -
-
-
-
É o único jeito que consegui pensar evitando fazer um select case monstruoso.
{Tenho uma Grid em um WUC. Uma property do WUC é o nome de uma tabela. Passo por property o nome de qualquer tabela para o WUC e no backEnd do WUC eu instancio uma classe com o mesmo nome da tabela (passado por parametro.). Se não fizer assim, preciso ter um select case pra cada classe que criar na minha aplicação}
-
Property : UsuarioDAO
'chamar a classe por StringDim classeDAO as new "UsuarioDAO" (exemplo)
Property : ClienteDAO
'chamar a classe por StringDim classeDAO as new "ClienteDAO" (exemplo)
OU
Property : UsuarioDAO
select case case "UsuarioDAO" ob = new UsuarioDAO case "ClienteDAO" ob = new ClienteDAO
-
Uma solução que pegaria bem no seu caso é utilizar o Unity Application Block
Consiste em:
Todas as suas classes implementam uma mesma interface
Ex:
UsuarioDAO: IEntidadeDAO ClienteDAO:IEntidadeDAO
Você cria uma classe mapper que registra todas as suas entidades
myUnityContainer.RegisterType<IEntidadeDAO, UsuarioDAO>("Usuario"); myUnityContainer.RegisterType<IEntidadeDAO, ClienteDAO>("Cliente");
Finalmente, ao invés de fazer o new das suas instâncias, você deixa que container do Unity faça isso pra você:
myUnityContainer.Resolve<IEntidadeDAO>("Usuario");// Retorna instância de UsuarioDAO myUnityContainer.Resolve<IEntidadeDAO>("Cliente");// Retorna instância de ClienteDAO
Gosto dessa técnica pois evita o alto acoplamento e dependências entre as classes.
(Se puder, pesquise mais sobre Injeção de Dependências)
Ou, um jeito mais simples é fazer os news encadeados dentro do seu switch case mesmo.
O problema disso é que pode gerar muitos pontos de manutenção caso as classes sofram alguma alteração, (inclusive afetar os pontos onde você faz o new das instâncias)
Espero ter ajudado
-----------------------------
Tiago Saraiva Ferreira
- Editado Tiago Saraiva Ferreira quinta-feira, 30 de agosto de 2012 04:17
- Marcado como Resposta Harley Araujo quinta-feira, 30 de agosto de 2012 11:19
-