ciao,

qualcuno sa come posso richiamare un assembly creato dinamicamente in memoria per passarlo come ReferencedAssemblies di CompilerParameters (senza scriverlo su file)?

mi spiego meglio :

codice:
public static class Estensore<T>
    {
        public static T Estendi(object tipo, string nomeClasse, string nameSpace, Dictionary<string,string> proprieta)
        {
            CSharpCodeProvider CSharpCodeProvider = new CSharpCodeProvider();
            
            ICodeCompiler Compilatore = CSharpCodeProvider.CreateCompiler(); 

            CompilerParameters ParametriCompilatore = new CompilerParameters();

            ParametriCompilatore.GenerateInMemory = true;
            ParametriCompilatore.IncludeDebugInformation = true;

            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                try
                {
                    ParametriCompilatore.ReferencedAssemblies.Add(asm.Location);
                }
                catch
                {
                    return default(T);
                }
            }

            StringBuilder CodiceSorgente = new StringBuilder();

            CodiceSorgente.Append("using System;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("using System.Collections.Generic;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("using Test;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("using System.Text;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("using Microsoft.CSharp;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("using System.CodeDom.Compiler;");
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("namespace "); CodiceSorgente.Append(nameSpace);
            CodiceSorgente.Append("\n");
            CodiceSorgente.Append("{\n"); 
                CodiceSorgente.Append("public class "); CodiceSorgente.Append(nomeClasse); 
                   CodiceSorgente.Append(" : "); CodiceSorgente.Append(tipo.GetType().ToString());
                CodiceSorgente.Append("\n");
                CodiceSorgente.Append("{\n");
                              
            foreach(string nomeProprieta in proprieta.Keys)
            {
                string nomeProprietaMaiuscola = nomeProprieta.Substring(0,1).ToUpper() + nomeProprieta.Substring(1,nomeProprieta.Length-1);
                string minuscola = nomeProprieta.Substring(0,1).ToLower() + nomeProprieta.Substring(1,nomeProprieta.Length-1);

                
                CodiceSorgente.Append("public string "); CodiceSorgente.Append(nomeProprietaMaiuscola);
                CodiceSorgente.Append("{ get{ return " + minuscola + ";} set{ " + minuscola + " = value; }}"); CodiceSorgente.Append("\n");
                
                
                CodiceSorgente.Append("\n");
                CodiceSorgente.Append("string ");
                CodiceSorgente.Append(minuscola); CodiceSorgente.Append(" = ");
                    CodiceSorgente.Append(@"""");CodiceSorgente.Append(proprieta[nomeProprieta]);CodiceSorgente.Append(@"""");
                    CodiceSorgente.Append(";");
            }

            
            CodiceSorgente.Append("public "); CodiceSorgente.Append(nomeClasse); CodiceSorgente.Append("() {");
            CodiceSorgente.Append("\n}\n}\n}");
            CompilerResults RisultatoCompilatore = Compilatore.CompileAssemblyFromSource(ParametriCompilatore, CodiceSorgente.ToString());            
            if (RisultatoCompilatore.Errors.HasErrors)
            {
                foreach (CompilerError Errore in RisultatoCompilatore.Errors)
                {
                    if (!Errore.IsWarning)
                    {
                        return default(T);
                    }
                }
            }
            Type t = null;
            for(int i = 0; i<RisultatoCompilatore.CompiledAssembly.GetTypes().Length;i++)
            {
                if(RisultatoCompilatore.CompiledAssembly.GetTypes()[i].Name==nomeClasse)
                {
                    t = RisultatoCompilatore.CompiledAssembly.GetTypes()[i];
                    break;
                }
            }
            object o = t.InvokeMember(nomeClasse, System.Reflection.BindingFlags.CreateInstance, null, null, null); 
            PropertyInfo[] properties = tipo.GetType().GetProperties//();
            (
                BindingFlags.CreateInstance
                //| BindingFlags.GetField 
                | BindingFlags.GetProperty
                | BindingFlags.Instance
                //| BindingFlags.InvokeMethod
                //| BindingFlags.NonPublic 
                | BindingFlags.Public
                //| BindingFlags.OptionalParamBinding
            );

            foreach (PropertyInfo property in properties)
            {
                if (property.CanWrite)
                {
                    object value = property.GetValue(tipo, null);
                    property.SetValue(o, value, null);
                }
            }
            return (T)o;          
        }
    }
usandolo così tutto funziona :

codice:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;


namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            User user = new User();
            user.Password = "2312";
            user.UserName ="paperino";
            Dictionary<string, string> dizionario = new Dictionary<string, string>();
            dizionario.Add("CodiceDiSicurezza", "123456");
            user = Estensore<User>.Estendi(user, "SuperUser", "Test", dizionario);
            writeProperty(user);
        }

        void writeProperty(User user)
        {
            PropertyInfo[] properties = user.GetType().GetProperties//();
            (
                BindingFlags.CreateInstance
                //| BindingFlags.GetField 
                | BindingFlags.GetProperty
                | BindingFlags.Instance
                //| BindingFlags.InvokeMethod
                //| BindingFlags.NonPublic 
                | BindingFlags.Public
                //| BindingFlags.OptionalParamBinding
            );
            this.dataGridView1.DataSource = properties;
        }
    }
    public class User
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}
ottengo ovviamente le proprietà della classe "SuperUser" più quelle ereditate da User.

Il punto e che mi piacerebbe fare una cosa del genere :

codice:
            User user = new User();
            user.Password = "2312";
            user.UserName ="paperino";
            Dictionary<string, string> dizionario = new Dictionary<string, string>();
            dizionario.Add("CodiceDiSicurezza", "123456");
            user = Estensore<User>.Estendi(user, "SuperUser", "Test", dizionario);
            //writeProperty(user);
            dizionario.Clear();
            dizionario.Add("CodiceDiSicurezza2", "123456");
            user = Estensore<User>.Estendi(user, "Admin", "Test", dizionario);
            writeProperty(user);
in questo caso, la seconda volta che chiamo Estendi, eredito da "SuperUser" (non da User), in quanto il suo nuovo tipo è appunto "SuperUser".
ora il problema è che non voglio scrivere l'assembly su file, lo voglio tenere in memoria, quindi volevo sapere se esiste un modo per caricarlo nei parametri del compilatore senza passare location.

codice:
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                try
                {
                    ParametriCompilatore.ReferencedAssemblies.Add(asm.????);
                }
                catch
                {
                    return default(T);
                }
            }
sicuramente è una ca***ta, ma ora ho un vuoto.
Grazie in anticipo per l'attenzione.