Hands on Plugin System Design Experiment - Blazor Build Series
January 22, 2024
• 1,183 views
In the second video of our Blazor web app build series, we look at doing a "spike" or a proof of concept for our plugin system! This video is longer than usual and much more resembles a live-stream kind of feel.
Join me as we explore building our ASP.NET Core Blazor web app and experiment with one of the social plugins we intend to integrate!
Have you subscribed to my weekly newsletter yet? A 5-minute read every weekend, right to your inbox, so you can start your weekend learning off strong:
h...
View Transcript
in this video we're going to dive into doing a spike for our Blazer web application we've been talking about building a Blazer web app that's going to allow us to measure things like our social reach across different Platforms in the previous video that I made which I'll link right up here you can check that out and come right back I started talking about the different concepts that I wanted to be able to introduce in this and did a really highlevel block diagram about different parts that I could see showing up in this system in this video we'll take a slightly different approach and jump into some code now when we're doing things like spikes or proof of concept we have to accept that a lot of the code we're going to write is going to get tossed out the entire point of this is to
have a little bit of a playground figure out and see what works what doesn't and have an idea for how we'd like to go forward ultimately I don't want to have to go rewrite this from scratch so we can try out some refactoring as we going along with this now before I jump over to visual studio just a quick reminder to check that pin comment for a link to my free newsletter all right let's start from scratch so we're truly going to get this Blazer application going right from the ground up and I've made a few videos on Blazer already but I need to share with you that Blazer is not my strong suit this is going to be a learning process for all of us and if you can learn alongside me I think that'll be really cool so what I want to do
in this case is make a brand new blazer app I'm going to give it a name and I'll click through the project setup but some of the settings that we're going to use they might not be things that we want to use in the final thing and that's totally okay we're just trying to get to a point where we can play with some code and see what's up I'm going to call our project social reach so we're going to have a project and a solution with that name I'm going to go with net 8 because I have that installed we'll use https I'm not really worried about authentication right now interactive render mode server side sure let's go with that to start and I do want to include some sample pages and I want to do that because I want to see what's there when
we start I know for a fact we're going to be ditching a lot of the sample code and that's cool but for me personally I learn best when I have things that are already in place and I can tweak and modify them all right so our project's been created and let's go have a look to see what we get when we start up so we have our program CS file I'll zoom out a little bit we can see that we have some familiar asp.net set up here right we got our builder for our web application do some service configuration build it and then we have some other options that are below before we start running it now with blazer we're going to have a lot of the stuff put into these components folders for me personally when we have things laid out by Pages like
this and then we have the layout I'm thinking that probably going with something like we could do vertical slicing or something else I know vertical slice architecture right now is being a little bit overhyped um I like delivering features in vertical slices I don't think that everything has to be vertical slice architecture but um I think that we'll probably be ditching some of these pages of course and as we start to put stuff together we should be thinking about the different pages and different things we want to see now I've made videos before on Blazer plugins and doing things in the user interface where we can dynamic have stuff showing up but I think for this I'm not necessarily interested in having different metrics and things like that show up across different pages right now so for example if I wanted to know how many
LinkedIn followers I have and how many YouTube subscribers I don't think right now that I want to have a page for each of those I want to have one page that has these overlaid on it so when it comes to doing plug-in design which I'm pretty confident I'm going to be going with I don't want to have plugins yet for things in the user interface I want to have plugins for my data sources so I want to call that out nice and early because that's probably going to come up pretty soon I'm going to go ahead and run this just so we can see it start up we can make sure that we're in a good spot and not having to deal with anything wonky before we try modifying things the last thing I want to have happen is that I start to touch the
code break everything immediately and then I spend a ton of time debugging just to see what I busted and this worked it started up just as we might might expect so we have our counter page our weather page and a homepage so I'm probably going to be ditching counter and weather because we don't need those but for now it's not going to add a lot of value if I go delete those and show you on the video I'm just calling it out is that's something we're going to want to remove so I'm thinking that I probably want to just use this homepage as a dashboard and then we can start to plot the different data that we want to see here all right so so far we have a dummy Blazer app set up and we're talking about putting some content onto the homepage that's
great but I think for me starting this Spike I'm not very interested in playing around with the user interface elements yet I'm more interested in seeing how we can lay out some of the backend in order to be able to fetch the data that we're interested in so I'm not going to go looking for different components or packages to be able to graph these things yet because I don't think that's going to be super interesting right at this moment I'm more interested in seeing what we can try to spike out and see if we have a little bit of a working proof of concept before we start plotting things because I know that if I have a set of data coming back and it's structured the way that I'm interested in it's going to be pretty easy to find something in the UI that we
can go plot some data I'm confident there's lots of libraries we can leverage for that and I want to call this out because as we're walking through this and treating this like a proof of concept or a spike I want you to be thinking about what's important for us to accomplish in that proof of concept the reality is even picking Blazer as a technology to go build this that should be part of a proof of concept if you were doing this in real life for me I already knew that I wanted to pick this technology to show it on the channel so that we could talk about it and learn it together but if you were building this for real for customers or for the business that you're working at if you wanted to do a proof of concept I would highly recommend that you
don't just pick the latest fanciest technology you put some thought into what technology you're going to pick that might mean picking things that your team is comfortable with that might mean picking something that is newer and fancier because your team needs to start moving from something incredibly old and Legacy and getting a little bit uncomfortable but there's so many different options to consider that you need to have that included in your proof of concept and not just choosing things blindly so I'm kind of skipping over that unfortunately because this was pre-selected I just wanted to mention that the other part that I'm trying to drive home here is what we want to focus on for the proof of concept I'm saying for UI elements not very interested but for backend things in terms of what we have access to I want to play around with
some of that first and there's no right or wrong answer here this is really about what types of things you're setting out to prove in the first place because I have a lower confidence level about the different things that we might have access to I want to start proving that first if I had lower confidence maybe in UI elements and assuming that we didn't have access to these types of controls I might say hey look I want to do a spike and go investigate what's online and to be honest I probably will have to do that at some point I just want to start with the backend changes first I'm going to pull up the tablet super quick I'm going to draw out the plug-in design that I'm thinking about and then I'm going to talk about perhaps one of the different platforms that we
can pick to start to see if we can look at accessing some data we can look what comes back on the API if we find a n get package that we like and I have one in mind because I've worked with it already before so I'm cheating a little bit but I think if start to play with that we can start to think about maybe a bit more of a generic approach to think about the other platforms that might have some of this data and how we might start to massage that in this way we can start to think about what our entities might need to look like now I'm jumping around a lot here and there's a lot of moving parts and this is going to be the way that I'm thinking about trying to build this system I'm not trying to tell you
that you have to go build systems this way I just want you to follow along and see how I think through it all right so we want to start talking about how we're going to build plugins and I showed this in the previous video a little bit but my idea is that we have these different data sources for the platforms that we want to pull uh social information from right so if we want to get our follower counts or our reach on different platforms we need to access these apis or we need to build scrapers and I think that these are two common ways that we're going to be accessing data ideally we're not writing web scrapers because it's a pain in the butt but if we need to we can start exploring that so the idea that I have is that I want to
have a database and we're going to see if we can even get to a schema today it might be way too early for that but we're going to have some database and in the previous video I talked about trying to get something running with a job scheduler and I think I might want to pick quartz for that I know there's quartz and hangfire that are both very popular libraries I've used neither of them but I've heard good things about both and I think I'm going to want to try using quartz for that so the idea that I have is that we'll have at least one job scheduler to start and this is going to be quartz and I'm just going to draw a little bit of a circular arrow that kind of goes back on itself because it's something that we will end up scheduling
but what I don't know right now is if we're going to have multiple scheduled jobs that go or if we have one big scheduler my gut tells me that per plug-in that we have we probably want to go build some scheduler for it but I don't know it might be totally overkill for us to try designing how that scheduling system is going to look right now but I know I want something recurring and something that's going to be controlling these other plugins that I'm about to show so we're going to have this job Schuler up top and that's going to be responsible for writing stuff into the database here so how does it get that data though right if it's running these jobs what are the jobs doing well that means that we have these plugins I'm just going to draw them as little boxes
here and what it's going to do is each job from the scheduler is going to ask these plugins to go fetch data right so I might want to use a different arrow for that so the if we're talking about data flow right the data is going to be coming out of the plugins and this is why I was saying I don't know right now if we want to have one scheduler controlling all of the different plugins maybe we go run one job and it goes in parallel or in serial I don't know right now and we'd go fetch and hit all these apis and run these scrapers something tells me that we probably want to go in the direction of being more modular with this and having different jobs that get scheduled per plugin but we'll come back to that I just wanted to illustrate
what I'm kind of thinking about with these different plugins and what the plugins are if you recall in the previous video I tried to draw these little clouds for the the different things that are going to be out on the internet that we're interested in but I'm going to start with some things in particular I want to start with Twitter because I've been more interested in trying to get active on Twitter I think that's a good one to start with I think back to you know what makes a good proof of concept or a prototype or a spike for me I'm interested in trying to get some Twitter information it's more relevant I want to start with that as part of proving this out uh some of the architecture is less of a spike for me because I've built systems kind of like this before
but I haven't used a third part job schuer I've kind of built my own so this part if I draw a box around it this part is new for me right I haven't used quartz before and this part with Twitter is new and I think that when I'm doing a Spiker proof of concept I'm setting out to go get new information right so the stuff that is well understood to me I don't want to spend too much time on now I might be spending a lot of time on it right this moment because I'm just trying to explain the thought process but what I'm highlighting is that I want to spend more time looking at Twitter and I want to spend more time looking at Quartz because these are going to be new things for me doing a plug-in system very comfortable with how we
design that the right way we'll have to see as we move along but the idea is that these plugins are going to be pulling data from these different sources we'll have other ones like I said I'm just starting with Twitter and we can pull up the I think there's a Nate package that I've read a little bit about um I think it's called tweet Envy we'll pull it up and see I might have the name wrong might be saying it wrong but we're going to use that nougat package we're going to pull the data from Twitter and we're going to have um an API that we build around that so I'll show you briefly um this is already going to be Overkill but I know that I want to have a plugin system built for this so I'll do a lightweight plugin that I'm thinking
about um the jober I don't think we're going to get to in this video I'll follow up the quarts part after this video we're going to do the plugin part I think for this um and we'll think about what needs to be on that plug-in API in order for the job scheduler to be able to access that plugin and try pulling some data from it so for this video in particular what we're going to look at is sort of this part here I know this is already getting messy so we're going to look at that part and then thinking about note I'm going to draw this thick line here at the top of the plugins and the reason I'm doing that is because we're not going to have it perfect yet but I want to think about having all of our plugins implementing a common
API and the reason I want to do that is because they are plugins and I don't want to have our job scheduler have to know how to call each individual plugin so to give you an example when we go to add a plug-in for Twitter and then Facebook and then YouTube and then LinkedIn and medium you name the platform that we're trying to get Social reach for when I go to build this I don't want to have code that sits there and goes if LinkedIn do this if Twitter do that to me that's not an extensible design I am comfortable Building Systems moving away from that so I just want to highlight that I want to think about what this API might be that's common but I want to fully acknowledge that there's no way at this point I'll get it right I just want
to start this conversation so that when we're looking at some of the data that we have access to we can start to think about what's feasible so for example I like thinking about building apis that when I call them they feel good to me as the caller and the caller in this particular case is going to be this job Schuler right it needs to be the thing that calls the plugin so from the perspect perspective of the job scheduler I want to make sure that it feels good to call this plug-in API however I don't know if it's realistic based on the data that we're going to want to have access to and the data that's available this problem gets extremely difficult when you start adding more and more plugins and the data that's available to you is more and more limited so for example
there might be apis that are publicly available and you don't need to have certain you know private access to go look up a follower count right if you go on someone's Social Media profile on most platforms a follower count is public but you might have a private profile and maybe on some platforms you can't see the follower count unless you have access to that private profile if that's the case it might be very difficult for us to just say across the board that we just want to get a follower count and we have all of the parameters we need easily we might have to think about what we have access to and refine the AP that we're building I'm calling this out early because as we add more plugins in this video series we may very well realize I'm going to make up a number
we get five plugins in everything's going great we have a nice common API we go to add the sixth plugin and we go wait a second you know this platform doesn't have what we need or it needs extra parameters passed to it do we have to come back to this API here and think about how we go build this in a more generic way or offer more context so we're not there yet but I'm trying to bring all this together hopefully that makes sense so far I think I want to jump back to the code we're going to have a look to see uh we're going to pull in that tweet Envy nougat package I want to see if I have a I'm just going to make a class somewhere and it's going to be our plugins uh I'm going to make a facade to
start and have that call the plugin so you can see how this is going to come together and we'll look at what tweet Envy offers us all right what I'll probably do is just start dumping code right into program.cs I don't know where the right home is for now and I don't want to worry about it but I think I want to have something like a Twitter plugin and like I mentioned I know I want to build a facade around this so I'm just going to start with that as well just a call out as well I probably will not have the word plugin in here once we start getting working I'm going to want to change what that plugin means so it might be something like Twitter data fetcher and it might be data fetcher facade but the word plug in is very likely
coming out and this is the point where I would like to start putting an API in place but as I said I don't know what we have access to on tweet Envy so I'm going to pull that nougat package in next so this is the one I was thinking of tweet Envy I like I said I think that's how you say it pull that in now I'm going to make a method just to see what we have access to and I am assuming it's in tweet Envy there we go and we can see there's an O name space a client some other things what else is on here models interesting so I'm just C like I don't know how this uh nougat package is organized right so everyone is going to have their own implementation and style of how they like to do things so
like having a whole thing for entities is a little bit weird to me because I would like to have my stuff grouped out by feature not have them grouped out by the the type of the thing that they are so kind of interesting um user entities see I'm thinking that I probably need something like a user or a profile like a user in social media probably has properties like follower count um but I don't know like I don't want messages so let's see what else we have so it looks like there's a users client which is cool um if I take a look at the interface let's go ahead can I new that up okay so this users's client is going to take in some parameters I'm not sure how to set these up quite yet I just want to see what we have access
to follow us okay so there's some methods where we can follow the user that we're interested in Block these are actions that we want to take but there are some get methods here get blocked get follower IDs interesting um get followers is there just a account that might be interesting there's a lot of stuff on this API really interesting but you can see like if you watch my other videos on fetching data to give you an example I don't want to pull back all of the followers um I don't personally want want to go run an iterator and even if I'm only going one at a time just count each one of them just to get a number I I just want to see if they have an API to get the count but I mean get followers so that's follow user get follower IDs
get users so maybe and again I'm just kind of playing around with this right now I don't really know there's get followers I say get followers iterator I don't know if I want that I want get follower IDs iterator kind of sucks um and it looks like there's a one oh this one here has by username so this should be mine and this says that it's an iterator which is interesting but it's not exactly like a built-in iterator in C it's its own type um so this is neat but I don't know what we have access to on the iterator itself so there's a cursor it's it's paging right um if it has a cursor it's basically a paging kind of approach next page there we go so in interesting uh I might have to go look up API docs for this and I recommend
that you do that kind of thing I just like exploring cuz this part's kind of fun for me but if you're trying to save time yeah API docks are the way to go I generally do this part first to poke around probably get stuck probably go to API docs but what else we had users client get followers async get follower IDs async so if we want to go use the async version here we have to put this as async and and then we have to have a task as the return type once we have that we can put the keyword await in front and it looks like this might be something we can do I guess it's going to try to pull back all of the IDS this does say friend IDs is there a difference between follower I don't know what the difference is
between a follower and a friend so this is something as part of this Spike that we'd have to go figure out I'm assuming it's followers friend might be like an overlap or something but again API docks are probably valuable but this is a little concerning to me because I mean for me I don't have a ton of followers so pulling back you know I have a few hundred followers or probably less than 300 on Twitter um hopefully you're watching this in the future at some point and you go wow I can't imagine when you only had 300 followers right um that would be cool but having a ton of these Longs come back is concerning to me and I think that's where we'd want to to go to the paging approach to start this is probably okay so we need to figure out how to
create this users client it looks like it needs a Twitter client and a a factory as well but that probably means that if I have a Twitter client set up like this I may just be able to get a user's client off of it and I can yeah so they take care of that for you which is cool and I just noticed there's a users V2 so let's go have a look at that again you're if you're watching this going this is frustrating like why don't you just show us the answer it's because I'm showing you my thought process right I have lots of other videos you can watch and they'll show you like how to get to the answer really quick but this is how I program and how I explore things I'm not a documentation reader and I should be I go to
the documentation after I've like to play around with things but I saw users V2 and I don't think that we were looking at a users's V2 client before so get user interesting so I wonder if I can get a user by the username so get Dev leader and then from there I wonder if it has some information on it so Dev leader will await this right so I'm going to move this line down because I'm having a feeling we probably don't want to use the V1 client if there's a V2 I don't know the answer to that though but we have a Dev leader user a co-pilot was saying follower count right after that's nice it's not there it seems uh user followers no public metrics follow there we go so this is great this is I'm glad we got to poke around a little
bit longer right so following followers um we'd be able to do things like uh listed and tweet I don't know what the difference is between listed and tweet kind of cool but going back to the API design right just to to pause for a moment we know that or at least in my opinion the minimum that I want to be able to do for these social media platforms is get a follower count for me the social reach in that regard is the most interesting part I don't think that over time it will be the most interesting part but I think it's really interesting to gauge growth now what will be really important is engagement rate right and engagement rate will have something to do with you know the number of times that you're posting things and the different types of interactions that happen that's going
to get a lot more complicated and I don't want to rush into that I might have to uh make follow-up videos later where we start moving in that direction and coming up with a new plug-in API or an extension of it a different version of it where we start looking at that but to start having just followers is very interesting that's the minimum that I think we need in this API coming from Twitter looks like we can get following so on some platforms maybe that doesn't make sense so I'm just trying to think out loud here you know the your typical social media platforms like Facebook Instagram Twitter they're all going to have this LinkedIn right they're all going to have this concept of you follow someone follows you regardless of it's subscriber follower anything like that I'm trying to think about publishing sites like
medium uh there's hash node there's a few others I don't know if a following so the the other way right I don't know if that's necessarily going to make sense and we could just to give you an example on the return that we get from this in terms of the API that we would have on our plugins we could do something like we always want to make sure we have a follower count and perhaps a foll count could be interesting to include but we might want to make it optional to start so it could be nullable the reason that I might want to put that on even from the beginning is that as we go explore some of this we might find it interesting that is we're trending things over time if there's a relationship between how many other people we're following and our follower
growth I don't want to sabotage the whole thing by making this a required field and then all of a sudden we reach some platforms where like that concept doesn't make sense so plugins as you can see can be really challenging to plan far ahead I wanted to say that like there's no perfect answer to this you're not I promise you you're not going to get the plug-in API right the first time and unless you do one plugin and you stop there and the reality is you're going to reach a point where you go ah you know what this doesn't quite fit and have to revisit some things it's quite literally like premature refactoring right if you have some code and you're refactoring it too soon you run into problems like this so what I'm thinking is maybe to start we have like a a record
dto that comes back so public sealed record and we will have our follower count and I'm going to put the following count on but like I said I'm going to make it nullable for now and that's only because I'm not sure if we're going to have access to it this is probably just Overkill to be talking about right now so I just wanted to kind of walk you through my thought process for including it and if I change this now on this task here I want to be able to return the social stats we could call this fetch social stats a sync we have that now should remember if it's going to be a syn what do we want to do all of the time do it early because it's way easier to put it in at the beginning uh a lot of people like
making these is optional so like having like a you know optional parameter setting it to default I don't I don't like doing that when I'm writing my own code because I want to make sure that I force myself to use the cancellation token and not take any shortcuts so if I don't have access to a cancellation token it gives me the option to pass in the default one or I refactor the code and start pass passing it in from higher up so that's my Approach personally and just kind of looking through what we have here the idea let's see if co-pilot can complete that look at that co-pilot is great and I need to make a new social stats and again co-pilot to save the day and I will return those social stats I'm going to put these formatted like this because that's my preferred
way to do it and already we're getting something kind of interesting forming here I don't know if this API takes a cancellation token it does not it seems okay interesting so that kind of sucks uh I don't want to go worrying about that for now um I'm going to leave the cancellation token on here and the reason I want to do that is because this is going to be the common API that we're forming up but just a good example right there's a cancellation token parameter that we're expecting and the Nate package that we use doesn't even support it we can explore if we need to cancel this some other way later but I also want to mention that this being instantiated in this method probably doesn't make a lot of sense right every time you go fetch do we want to make a new
client I'm not sure um I don't know if we have to worry about that for now uh is this disposable let's double check it's not so okay um this might be something that we can do like this and we would have to find a way to pass in our our key and secret so I'd have to set up something on Twitter to do that but I'm not doing that in this video I just want to show you how I'm coming up with an initial API and what we have access to when we're working with Twitter so what I would do from here just to kind of show you is I would have this on a public API here for our facade we're going to have to have a way to pass in plugins the facade but I wanted to call out too that when we're
talking about this API signature this key and secret right these are specific to Twitter now if I put the key in the secret on this API here that might make sense for some other social platforms where to authenticate you just need an API key and an API secret but I don't think that that's going to be something that's common across everything and the reason I say that is because if we even need to go build a web scraper we aren't going to have a key and a secret by definition we're scraping the web and we're not using an API so if I want to keep this common I need to be thinking about as we go what does this implementation need and what are other implementations either going to need or not care about so if this implementation needs a key and a secret I'm
probably going to have to pass that in Via dependency injection into this and just to give you an example what this Twitter configuration might look like thank you co-pilot so we'd have something like a Twitter config right and I mentioned dependency injection I am a fan of using primary instructors on classes when things are dependency injected you may not be and that's okay because I know that this Twitter config is mutable now at least in this version of net depending when you're watching this right maybe it's different but this is a mutable field which means I could write code like this and I could assign null to it or make a new Twitter config but I like using primary Constructors this way when I have dependency injection because I never personally I never write code that's going to be assigning Fields like this that are
passed in just as a side note so what we can do now is get rid of this consumer key and consumer secret as strings and that means we have these being passed in on this configuration now the other thing that I just noticed is we have this username as well here's another good note so on the API call that we have on our plugin does it make sense to put the username here I want you to pause and think about this for a moment because this is my Twitter username right and it's a string now on Facebook do I have a Facebook page that's a string I do on YouTube do I yes I do but are there going to be situations where I don't need a username are there going to be situations where my ID is not a string but it's a number
to me early on at least this early on I think the answer is I can't safely say that everything is going to need a username so what I'm going to do is move this part in particular onto the Twitter config now that means that down here I can go move that away and I'm just thinking out loud here username with Twitter is probably Overkill I can probably just have username it's a little bit redundant to have Twitter in there again and suddenly this is kind of shaping up to be pretty interesting right again I haven't run this I haven't proved that it works but this API is looking pretty good to call right it's really simple doesn't need any parameters except a cancellation token but we got that covered the stats that we have coming back are just follow and following optionally and we know
that with this tweet Envy package we have some access maybe to some other things that we can explore later and see if that's an interesting concept that will apply to other platforms but let's go back up to this facade for a moment on the facade I like doing this thing where the API and it's not always this way but I like having a very similar API to what's on the plugin and sometimes it's identical and other times it's not so what do I mean by that some facades I have that for plugins need to do an aggregate across a bunch of plugins so what they will do is take all of the data from the plugins all these results and put it into one result if that's the case they might share a common API like this however if they're not doing an aggregation of
the data and they just need to get a a list of all of the data then I need to change the API to have it as such so the difference here is that this is a multiple return value value API and if I scroll down this is not so I don't think that I'm going to be aggregating into one social stats uh record we might find later that we want to have a single social stats and maybe it's addictionary lookup or something like that I don't know yet I don't think that's the direction I'd like to go this early especially but when it comes to this facade the idea is that it needs to be able to ask all of the plugins but we only have one right so this facade to go start it just to show you what this would look like right
away and co-pilot is getting all ahead of schedule here we don't have a GitHub plugin co-pilot um so Twitter plugin if I just hit tab that's way too chaotic so Twitter plugin and then I'm going to do the same thing where I have a primary Constructor like this and the idea with only one plugin just to keep it super simple would end up looking something like this right but you can probably see that this pattern is not going to be very extensible because if we want to keep going to add plugins it's going to do what co-pilot is thinking about and adding you know all of these different plugins here and just the argument list is going to get nuts but what we can do is we could make an innumerable right of all the different plug-in types that we want to support and that
way actually I probably want to make this an I read only list I'll explain why in just a moment but probably want to have this plugins collection being passed in and then what I would do is something like than co-pilot so we get rid of this down here and I'll pause just to kind of explain the different changes I've made this isn't going to be Twitter plugin we need a common interface so that's going to be the next part is what common interface do we want why did I use an I readon list well depending on how these plugins are instantiated especially the collection of them I want to make sure that if that's an expensive of operation to go create the plugins that I have it fully materialized before it gets here that is every time that I call this for each loop I
don't want this to be an iterator plugins to be an iterator so that it goes and fetches and recreates all of the things once again I want them to be created one time and not worry about it so I'll force that to happen with this readon list and then what we're doing here is kind of interesting and I think to start it's probably fine but if you recall what I was saying earlier about the scheduler having a job scheduler call the different plugins this is an interesting opportunity that we may want to come back and revisit because can we/ should we do these plugins in parallel right so we have one job scheduler that schedules one job and goes through this facade and then sequentially asks each social media platform tell me your followers and add it to this list we could do that and
that might be perfectly fine to start right I think in fact I will probably just do that to start because it's very simple and straightforward what we could do is change it so that we do a similar thing one job scheduler triggers one job and this facade does them in parallel right so we still have the same API on the facade but this is not a for each Loop anymore it would be like a parallel for each or a task when all we could do that or yet another variation is that we have auler that creates multiple jobs right and each job is responsible for one other plugin that means that this facade concept technically goes away I would have to go move the logic for how the scheduler needs to know which plugin to go run into something like the scheduler itself this facade
if we want to do multiple jobs you know one per plugin this facade might go away entirely but to keep it simple I think I will have a scheduler with one job calling this facade and it will just run them sequentially like this so this is my current thought process for how I'd like to structure this and that would mean that just to give you an idea if we go back up to the Blazer app itself right the way that this gets triggered we're probably going to need a background service right an asp.net core background service we're going to need some storage so we haven't talked about these parts yet the job scheduler itself I talked about using quartz and I haven't used it before so we'll explore that together we're going to use quartz and wire that up here in this part of the
code somewhere all ahead of time right there's not a UI element that we're pressing to go trigger this stuff so we'll get all that wired up and then that job scheduler is going to be responsible for calling into this plug-in facade so just to give you a brief idea if we had like a job class and I don't I've not used quartz before I'm just kind of making this up for something that I would expect to be able to see it needs to be able to call the plug-in facade and I just realized that we never made up the common API for this so let's go do that now we'll use a quick refactoring shortcut here I'm just going to extract this and I'm going to call it um I social data fetcher right so we have a social data fetcher that means that this
facade is going to take in the social data Fetchers just doing a little bit of renaming so what we have right now is data Fetchers for social and that would mean that this job is probably going to need some type of access to this and I'll have to see in courts how this is handled um so we'd have this fetcher and in here somewhere it's going to have to be able to say that it's going to go fetch that stuff right so it's going to get the social data then it's going to have to do something like WR to the database and then I don't know I don't know what else it might have to do at this point so the job Schuler will go will go create some typ type of job like this using dependency injection or something else hopefully we can pass
in this facade and then when we go run that this is going to be a collection of social data that comes back right now we only have one plug-in so an array or a list of one single thing and we'll go right that to the database and if you recall in the diagram I showed this is just to populate the database because I want to be able to have snapshots of growth over time once we have that in there we can go look at building the other part that is just some UI logic to go fetch stuff from the database when we want it and you know repopulate a graph that we'll find some library for and I think that's a good first step in the direction for getting our plug-in design put together so we talked about looking at one platform so far Twitter
we looked at what we can get from Twitter at least with this one nougat package that I've heard is pretty popular seems like it's pretty straightforward to call we look what we have access to and tried making some API that our facade might use I fully acknowledge that as we start to add more plugins into this so the different platforms like LinkedIn YouTube other publishing sites that this API very well might change and we're going to be in a position where we need to look at what we have access to Across the different platforms and what's going to make it a nice convenient API to call so as we go forward some things we can do in this video series are add more plugins we've kind of seen one already so I might do a bit of a pivot into something like the job scheduler
I think that will be a good next video for this series we can look at Quartz together see how some of this lines up from there we'll need to see how we can write to a database so I don't use n framework core a lot I like doing handrolled SQL queries but I'm going to try doing a spike continuing on in this path to use Entity framework core so we're going to go from having one Twitter plugin through our facade through the job scheduler which is quartz that'll be the next video we'll write that all to Entity framework once we have that I'm going to go to the next part which is fetching the data from the database to put in the UI at that point we have one feature completed end to end and I think that's going to be a really exciting moment
because from there we can continue to expand it by adding more plugins and I think that's where we're going to really see the power of plugins and some of the complexity show up when some things don't line up so I hope you found this insightful I know it was pretty long but I hope you got to see some ways that I think about solving problems and approaching building some simple systems like this thanks and I'll see you next time
Frequently Asked Questions
What is the purpose of the spike in the Blazor web application?
The purpose of the spike is to create a proof of concept for our Blazor web application that measures social reach across different platforms. It's a way for us to experiment with code, see what works and what doesn't, and ultimately lay the groundwork for the final product.
Why are you using a plugin system for data sources instead of UI elements?
I'm focusing on a plugin system for data sources because I want to ensure that we can dynamically fetch data from various social media platforms. At this stage, I'm more interested in establishing a solid backend that can retrieve and process data rather than getting caught up in the user interface elements.
How do you plan to handle different social media platforms in the plugin design?
I plan to implement a common API for all plugins, which will allow the job scheduler to interact with each plugin without needing to know the specifics of each platform. This way, we can add new plugins for different social media platforms while maintaining a consistent interface.
These FAQs were generated by AI from the video transcript.