Avatar billede Droa Seniormester
25. oktober 2016 - 15:16 Der er 2 kommentarer og
1 løsning

Events og filtrering til rasing

Hej eksperter

Jeg sidder og vil prøve og lave noget smart/dumt.

Jeg har lige pt et Event der kan blive abonneret af 3. part plugins, som jeg kalder onRecievePackage.

dog vil jeg gerne gøre det mere fleksibelt, da en pakke kan indeholde custom metadata, og ikke alle plugins behøver at modtage pakker de ikke har noget med og gøre.

f.eks hvis pakken ser sådan her ud.

<data xmlns="http://schemas.domain.tld/schema1.xls">
<name>TestName</name>
<race>DarkOrc</race>
<level>1</level>
</data>

så vil jeg gerne kunne registere mit plugin til kun og modtage hvis en pakke bruger namespace "http://schemas.domain.tld/schema1.xls"

det er rigtigt nok at man bare kan oprette

event Schema1Delegate Schema1Recieved^

men det er ikke rigtigt så dynamisk. er der en måde og kunne oprette dem efter namespace?

Dictionary<namespace,event> nsevents

også kunne raise dem ved og gøre noget lignene

nsevents[namespace]();

på forhånd tak
Avatar billede arne_v Ekspert
25. oktober 2016 - 17:00 #1
Ide:


using System;
using System.Collections.Generic;
using System.Linq;

namespace E
{
    public delegate void D(string msg);
    public class Standard
    {
        public event D ToDo;
        public void Test()
        {
            ToDo("Standard");
        }
    }
    public class Custom
    {
        public List<D> ToDo = new List<D>();
        public void Test()
        {
            ToDo.ForEach(d => d("Custom"));
        }
    }
    public class CustomWithFilter
    {
        private List<Tuple<string,D>> ToDo = new List<Tuple<string,D>>();
        public void Add(string key, D d)
        {
            ToDo.Add(Tuple.Create(key, d));
        }
        public void Test(string filter)
        {
            ToDo.Where(t => t.Item1==filter).ToList().ForEach(t => t.Item2("Custom with filter"));
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Standard std = new Standard();
            std.ToDo += (msg) => Console.WriteLine("A: {0}", msg);
            std.ToDo += (msg) => Console.WriteLine("B: {0}", msg);
            std.Test();
            Custom cust = new Custom();
            cust.ToDo.Add((msg) => Console.WriteLine("A: {0}", msg));
            cust.ToDo.Add((msg) => Console.WriteLine("B: {0}", msg));
            cust.Test();
            CustomWithFilter cwf = new CustomWithFilter();
            cwf.Add("A", (msg) => Console.WriteLine("A: {0}", msg));
            cwf.Add("B", (msg) => Console.WriteLine("B: {0}", msg));
            cwf.Test("A");
            cwf.Test("B");
            Console.ReadKey();
        }
    }
}
Avatar billede Droa Seniormester
25. oktober 2016 - 17:18 #2
det virker langt mere elegant en min egen løsning, mange tak for ideen :)
Avatar billede arne_v Ekspert
25. oktober 2016 - 19:19 #3
Der er ikke noget galt med Dictionary ideen - den passer fint ind.

Men jeg tror at List er mere fleksibel, se flex loesningen nednfor:


using System;
using System.Collections.Generic;
using System.Linq;

namespace E
{
    public delegate void D(string msg);
    public class Standard
    {
        public event D ToDo;
        public void Test()
        {
            ToDo("Standard");
        }
    }
    public class Custom
    {
        public List<D> ToDo = new List<D>();
        public void Test()
        {
            ToDo.ForEach(d => d("Custom"));
        }
    }
    public class CustomWithFilter
    {
        private List<Tuple<string,D>> ToDo = new List<Tuple<string,D>>();
        public void Add(string key, D d)
        {
            ToDo.Add(Tuple.Create(key, d));
        }
        public void Test(string filter)
        {
            ToDo.Where(t => t.Item1==filter).ToList().ForEach(t => t.Item2("Custom with filter"));
        }
    }
    public class Map
    {
        private Dictionary<string,List<D>> ToDo = new Dictionary<string, List<D>>();
        public void Add(string key, D d)
        {
          if(!ToDo.ContainsKey(key))
          {
              ToDo.Add(key, new List<D>());
          }
          ToDo[key].Add(d);
        }
        public void Test(string filter)
        {
            ToDo[filter].ForEach(t => t("Map"));
        }
    }
    public class CustomWithFlexFilter
    {
        private List<Tuple<string,D>> ToDo = new List<Tuple<string,D>>();
        public void Add(string key, D d)
        {
            ToDo.Add(Tuple.Create(key, d));
        }
        public void Test(Func<string,bool> f)
        {
            ToDo.Where(t => f(t.Item1)).ToList().ForEach(t => t.Item2("Custom with flex filter"));
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Standard std = new Standard();
            std.ToDo += (msg) => Console.WriteLine("A: {0}", msg);
            std.ToDo += (msg) => Console.WriteLine("B: {0}", msg);
            std.Test();
            Custom cust = new Custom();
            cust.ToDo.Add((msg) => Console.WriteLine("A: {0}", msg));
            cust.ToDo.Add((msg) => Console.WriteLine("B: {0}", msg));
            cust.Test();
            CustomWithFilter cwf = new CustomWithFilter();
            cwf.Add("A", (msg) => Console.WriteLine("A: {0}", msg));
            cwf.Add("B", (msg) => Console.WriteLine("B: {0}", msg));
            cwf.Test("A");
            cwf.Test("B");
            Map m = new Map();
            m.Add("A", (msg) => Console.WriteLine("A: {0}", msg));
            m.Add("B", (msg) => Console.WriteLine("B: {0}", msg));
            m.Test("A");
            m.Test("B");
            CustomWithFlexFilter cwff = new CustomWithFlexFilter();
            cwff.Add("A", (msg) => Console.WriteLine("A: {0}", msg));
            cwff.Add("B", (msg) => Console.WriteLine("B: {0}", msg));
            cwff.Test(s => s.StartsWith("A"));
            cwff.Test(s => s!="A");
            Console.ReadKey();
        }
    }
}
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