Avatar billede keepy Seniormester
01. juni 2016 - 11:09 Der er 6 kommentarer og
1 løsning

Event fra DLL mod service

Hej

I min service prøver jeg at abonner på et event der kommer fra en dynamisk indlæst dll, men jeg får følgende fejl.
Object of type 'System.EventHandler' cannot be converted to type 'TestDll.Response+EventHandler'.

Nogle der kan komme med et hint?

Koden i min service ser sådan ud.

      private bool GetDataFromDll(DllType Data)
        {
            bool Status = false;
            string Path = "c:\\temp";
            try
            {
        Assembly myassembly = Assembly.LoadFrom(Path + "\\" + Data.TypeNumber + ".dll");
                Type type = myassembly.GetType(Data.TypeNumber + ".Class1");
                Type response = myassembly.GetType(Data.TypeNumber + ".Response");
                object instance = Activator.CreateInstance(type);
                object instanceResponse = Activator.CreateInstance(response);
                MethodInfo[] methods = type.GetMethods();
                EventInfo a = response.GetEvent("DataReceived");

                if (a != null)
                {


                    instanceResponse.GetType().GetEvent("DataReceived").AddEventHandler(instanceResponse, new EventHandler(DataReceivedEventHandler));
                    object res = methods[0].Invoke(instance, new object[] { Data });
                 
                }


            }
            catch(DllNotFoundException ex)
            {
                Status = false;
            }
           
            return Status;
        }
        private void DataReceivedEventHandler(object sender, EventArgs e)
        {

        }


Koden i DLL ser sådan ud.
public class Response
    {
       
        public event EventHandler DataReceived;

        public delegate void EventHandler(object sender, myEventArgs e);

        public bool PostAllRegistrationData()
        {
            bool Status = false;
           
            myEventArgs DataReceiveDetails = new myEventArgs();

            DataReceiveDetails.ata = "muh";
            try
            {
                DataReceived(this, DataReceiveDetails);//Event
            }
            catch (Exception ex)
            {

            }

            return Status;
        }

    }
    public class myEventArgs : EventArgs
    {
        public string ata { get; set; }
    }
Avatar billede keepy Seniormester
01. juni 2016 - 15:33 #1
Jeg fik lavet lidt om i min serivce og nu virker det lidt bedre, dog bliver DataReceived ved med at være null.

var assembly = Assembly.LoadFrom(Path + "\\" + Data.TypeNumber + ".dll");
                    var types = assembly.GetTypes();
                    var internalClassType = types.FirstOrDefault(t => t.FullName == Data.TypeNumber +".Class1");
                    var myArgsType = types.FirstOrDefault(t => t.FullName == Data.TypeNumber + ".myEventArgs");
                    var eventInfo = internalClassType.GetEvent("DataReceived");

                    var methodInfo = typeof(DllRequest).GetMethod("MyHandler");//skal omdøbes til DataReceivedEventHandler
                    var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), typeof(EventArgs) });
                    var generator = method.GetILGenerator();
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldarg_1);
                    generator.Emit(OpCodes.Call, methodInfo);
                    generator.Emit(OpCodes.Ret);

                    var internalClass = Activator.CreateInstance(internalClassType);
                    eventInfo.AddEventHandler(internalClass, method.CreateDelegate(eventInfo.EventHandlerType));

object res = methods[2].Invoke(instance, new object[] { Data });
Avatar billede arne_v Ekspert
01. juni 2016 - 16:40 #2
Skal

public delegate void EventHandler(object sender, myEventArgs e);

vaere der???
Avatar billede arne_v Ekspert
01. juni 2016 - 16:43 #3
Hvad er det du oensker at opnaa?

Den kode ser meget "special" ud!
Avatar billede keepy Seniormester
01. juni 2016 - 21:15 #4
Jeg loader dll i runtime og jeg kender ikke så forhånd hvilken dll jeg vil anvende, derfor det ser lidt mærkeligt ud.
Dll raiser et event når dens opgave er færdig, og her skal servicen gribe eventet og gøre noget med de argumenter der er med.
Avatar billede arne_v Ekspert
02. juni 2016 - 05:48 #5
Problemstillingen er helt normal.

Men loesningen er normal meget simplere.

Du har i enten din EXE eller i en speciel API DLL definition af et interface med en event.

Du har et antal DLL med klasser som implementerer dette interface.

Din kode i EXE loader navngiven klasse med Assembly.Load og type caster til interface og resten af koden er helt "normal".
Avatar billede keepy Seniormester
02. juni 2016 - 07:59 #6
Hej Arne

Du har vel tilfældigvis ikke et eksemple jeg kunne se?
Avatar billede keepy Seniormester
02. juni 2016 - 11:15 #7
Hej
Jeg tror jeg fik den, tak for hjælpen

/**************************************Service projekt Start*****************************************************/

public Class1
{
  Assembly assembly = Assembly.LoadFrom(Path + "\\" + Data.TypeNumber + ".dll");// f.eks. testdll.dll
                                                                                       
            Type type = assembly.GetType(Data.TypeNumber + ".Class1");
            IEventHandler handler = Activator.CreateInstance(type) as IEventHandler;
            var types = assembly.GetTypes();
            var internalClassType = types.FirstOrDefault(t => t.FullName == Data.TypeNumber + ".Class1");
            var eventInfo = internalClassType.GetEvent("DataReceived");
            eventInfo.AddEventHandler(handler, new EventHandler<myEventArgs>(DataReceivedEventHandler));

            //Kun til test
            MethodInfo[] methods = type.GetMethods();
            object res = methods[3].Invoke(handler, new object[] { Data });
}

public interface IEventHandler
{
    void HandleEvent(object sender, myEventArgs e);
}

public class myEventArgs : EventArgs
{
    public myEventArgs(DllrxType dllData)
    {
        DllData = dllData;
    }
    public DllrxType DllData { get; set; }
}

/**************************************Service projekt Slut*****************************************************/
/**************************************DLL projekt Start********************************************************/

public class Class1 : IEventHandler
    {
       
        public event EventHandler<myEventArgs> DataReceived;

        Repuest reg = new Repuest();
        Response d = new Response();


        public void HandleEvent(object sender, myEventArgs e)
        {
            DataReceived(this, e);
        }


        public bool DLL_Logic(Service.Dlltx Data)
        {
            try
            {
                Service.Dllrx newData = new Service.Dllrx();
               
                newData.ErrorMessage = "Det gik ok!";
                HandleEvent(this, new myEventArgs(newData));
            }
            catch (Exception ex)
            {

            }
            return true;
        }
    }



/**************************************DLL projekt slut*********************************************************/
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester