Coding Blocks - Aspectacular with Vlad Hrybok – You down with AOP?

Episode Date: April 1, 2014

You down with AOP? This week we’re talking with Vlad Hrybok about his spectacular Aspect Oriented Framework: Aspectacular. Highlights include lots of Design Patterns, Acronyms, Buzzwords and…Duff ...Beer? ChangeLog Interesting debate about SOLID principles An attempt at a completely SOLID implementation of TicTacToe Great feedback on /r/csharp Interesting viewpoint from an anti-craftsman on dotnetrocks, great […]

Transcript
Discussion (0)
Starting point is 00:00:00 you're listening to coding blocks episode nine subscribe to us and leave us a review on itunes stitcher and more using your favorite podcasting app and visit us at codingblocks.net where you can find show notes examples discussion and more send your feedback questions and rants and comments to comments at codingblocks.net and follow us on twitter at coding blocks and on facebook at facebook.com slash coding blocks don't forget uh google plus there plus.google.com slash communities slash one one three four three seven zero six eight nine zero zero five five nine two seven six four four five how do we need to repeat that if you're listening in the car we know you got that
Starting point is 00:00:48 hold on here guys no rewind get a pencil all right so um and with that welcome to coding blocks i'm alan underwood i'm joe zach and i'm michael outlaw And today we have a special guest. His name is Vlad Hrybok. Hello. And he's going to be joining us and be speaking about Aspectacular here very shortly. So Joe's going to get us some podcasting news. We've got a lot of follow up on the last couple episodes. And so we have a few things we want to mention. First of all, episode seven on Reddit, we had a really nice discussion with someone named ground wolf and a few other people and we'll have that link in the show notes but um i had some really uh some interesting things to say about the solid principles kind of contrary to what we
Starting point is 00:01:34 talked about and an alternate point of view so i thought that was cool and also around the same time period actually there was an episode of dot net rocks with alan stevens who was arguing for a more pragmatic approach of software versus kind of the craftsmanship approach that we were talking about in this solid episode so we'll have a link to that in the show notes as well as well and speaking of reddit i finally posted my solid tacto solution up on github and got some really good feedback on slash R slash C sharp and that was really cool. So I'm still learning a lot and still finding out how difficult it is to really try to do something
Starting point is 00:02:13 by the book. So I love for you guys. Did any of your classes, did they do anything? There's a couple classes that actually do stuff and the rest is basically just empty interfaces. I think it is like 40-something classes with 1,200 lines of code, but most of that is actually test code.
Starting point is 00:02:33 But shouldn't you only have one empty interface? Because then all your other empties are repeating the first ones. They're not dry. Well, there's IEmpty, but then there's a bunch that implement that. Now that's solid. Yeah, solid as rock. So also, this actually harkens back to episode one. One of the things we talked about a little bit were the limitations of interfaces and things you can't do.
Starting point is 00:02:55 Like you can't implement interfaces on existing code like third-party libraries. And you also can't say that anonymous classes meet certain interfaces. But this company named Econ Benefits put out a library on GitHub, open source, and MIT licensed, which is called Impromptu Interface, and it lets you do just that. It basically uses a kind of dynamic proxy approach, which we'll talk about later, to slap some interfaces onto existing stuff. I thought that was really cool. Also,
Starting point is 00:03:30 we've got a lot of alsos this time. There's a new Pluralsight course from Troy Hunt about OWASP and web security. He's actually the one that we talked about before. He did that at OWASP and.NET. Yeah, he had a great Pluralsight video that went over all of the different OWASP attack types
Starting point is 00:03:50 and everything. It was really good. Yeah, and I think it was out in 2010. We'll have to verify that. But this is basically kind of like a refresh of that, it looks like. So really excited to watch that. Hey, where are you going to be?
Starting point is 00:04:02 Yeah, so where am I going to be? Well, this podcast will probably come out after the uh windows azure boot camp 2014 in atlanta but i will be there so make sure you come up and say hi if you're going to be there too um also the great wide open conference in atlanta i joe will be there and uh so if you're listening to the show come up say hi and uh let me know how you feel about it. Has anyone else got Tom Petty playing in their mind when they heard that announcement? Don't come around here no more.
Starting point is 00:04:31 I was thinking more like Into the Great Wide Open, but yeah, sure. Okay. Better than free falling. All right. All right. So, again, we have Vlad here, and he has created a solution that is a little more than just a little popular. It's called the UltiDev web server, and he's had some pretty major clients of that, and we'll let him talk about that in just a second. And then he's also the author of Aspectacular, which is going to be the focus of this show here in just a minute.
Starting point is 00:05:03 But Vlad, do you want to fill us in real quick on UltiDev? Oh, yeah, absolutely. So UltiDev web server, it's my little pet project that I've been doing for a while. I started back in 2006 with the offshoot of what was a Microsoft Cassini web server example. I was doing something else at the time and decided that I just put this little example in the rapid in a Windows service and just put it out there and see what people do
Starting point is 00:05:31 with it. To my astonishment, it was used many, many, many times by lots of people. Like a hundred? No, it started with hundreds, but then it went to thousands and recently it went over a million installations. That's crazy.
Starting point is 00:05:48 That's crazy. Yeah. So it's all of the web server product line, product iterations are probably like 10 right now. So as you, dear listener, can hear, Vlad is not exactly from around here and and there's a funny story behind this because one of the very first times i ever met vlad we uh we happen to go out to eat and you know we're making small talk as you do right and so i asked him i'm like hey man so so what do you do for fun? And his answer was, I write web server. And I swear to God, both me and Outlaw just kind of looked at each other like, I think there's a language barrier here.
Starting point is 00:06:35 I don't believe he understood the question. And then come to find out, he understood perfectly. Like, that's what he likes to do. He really does write web server. In my country, does write web server yeah in my country everyone writes web servers i felt like i did nothing with my life yeah exactly like all of a sudden our programming prowess amounted to nothing all in like one statement i got a skateboard yeah and i actually i heard this story and uh i was like oh i think i'm gonna like this guy
Starting point is 00:07:05 so yes that's vlad and uh he is he is an accomplished uh developer and one of the better i've seen so uh we're excited to have him on here thank you yeah so as uh alan mentioned we're you know the main topic of this uh this show is going to be around aspectacular but before we get into that we really want to cover a little bit of history about, well, what are Aspects? So Aspects is a concept that is not really new, but it's a way of implementing cross-cutting concerns. And cross-cutting concerns is all of the fluff and different things that we do around our business logic. Okay. all of the fluff and different things that we do around our business logic. Okay, so if I could give an example on that then, so maybe the code that you would often repeat inside of a method, right?
Starting point is 00:07:55 Like null checking, for example. Or logging. Logging would be another great example. Yeah, exactly. Logging is something that comes to mind really readily, but how we all happen to write our business logic. Yeah, exactly. Logging is something that comes to mind really readily. But how we all happen to write our business logic? We always start with just something real simple, just calling the database, getting data back, returning them. And this is how we tell our managers that, yeah, we are done ahead of schedule and it's working fine.
Starting point is 00:08:21 And then later we find out that something is a little bit too slow and something is, some connection is brittle and requires the retry. And then we want to find why these certain places the code works slower than other places we want to performance monitor it. So we start finding out all those things that are not necessarily functionality of business logic but actually required to be implemented. And usually, almost invariably, it's an afterthought, and it should be an afterthought. And what aspects are classes that allow you to implement those afterthoughts exactly as afterthoughts, not mingling them and mixing them into your actual business logic. And properly done AOP programming of the DAO and business tier is nothing more than allowing you to simply write what you would write as a 15-year-old programmer
Starting point is 00:09:22 just hitting the database return data back and not thinking about anything else. Yeah, so it's nice. Your classes really get to be very simple and, you know, as an S in SOLID, single responsibility. It's basically doing just what you think it's doing. It's not messing with the logging or the security or automatic retry logic.
Starting point is 00:09:39 It's just doing what the method name says. Yeah, he explained that perfectly for the cross-cutting concern. So it really does help you keep your code just easy to read. Yeah, great explanation. Yeah. And on the subject of SRP, there's one Michael actually just mentioned, the don't repeat yourself.
Starting point is 00:09:59 And it's another acronym that kind of ties in this a little bit. And it lets you get some of those things like logging or security checks. Instead of copying and pasting those one, two, three lines all over the place, you can extract that into one class, have it one spot, and then basically configure it to happen where you want it to happen. Yeah, absolutely. All right, and so what's about this with the design patterns of the interceptors and the decorators? Yeah, it's just if you're a design pattern nerd, if you've got the Gang of Four book,
Starting point is 00:10:29 then something that's going to end up coming up a lot in this show are basically interceptors or decorators, which are a way of kind of adding functionality to functionality without actually modifying the code underneath, which is kind of another acronym there, the OCP, the open-close principle from Solid, episode number seven. And so if you just wanted to look that up, that's something we're going to be talking about quite a bit, I imagine. And so one of the questions that came up, and I had actually done a little bit of research on prior, is AOP, IOC? You said a whole lot of letters there you're right so aop aspect oriented
Starting point is 00:11:07 programming right yeah we're gonna get the acronyms out of the way up front yes we can move on yeah so aop aspect oriented programming which obviously we're talking about here and then ioc is inversion of control and really they do they basically address two different problems aop is exactly what vlog just mentioned a minute ago about cross-cutting concerns, your logging, your retries, anything like that that needs to be tacked on top of things. IOC is more about being able to inject dependencies, which we did talk about in Episode 7 quite a bit. And the difference is IOC is more used for making sure that that you're not
Starting point is 00:11:47 newing up code it's it's so that dependencies are there at the time that the class is called and it's actually usually done via a framework for you for creating and newing up these projects where aop is a completely different concern this is more about what are the additional things that you need to tack on to code that exists. So one, AOP, again, what do you need to wrap around this thing to make it better? IOC, how do you actually instantiate your classes? That's really two different things. Right. But you're talking about IOC container specifically. Yes. Not the IOC pattern. Correct. Yes. In this context, you can think of many more types of inversion of control. For example, overriding a virtual function is also inversion of control.
Starting point is 00:12:50 Supplying a delegate is inversion of control. And pretty much if you started with programming Windows in the 1990s, you had to write those event handlers. That also is inversion of control. Inversion of control is a phenomenal pattern. It's one of the most useful to keep yourself dry, do not repeat yourself, and to make sure that your code is highly reusable.
Starting point is 00:13:16 And with the advent of latest features in C Sharp that makes C Sharp much more functional as a language, it really adds to the inversion of control as a pattern a lot, and it makes your code really expressive and clean. So if we were to go really nerdy of whether AOP is AOC... Oh, I think we're already there.
Starting point is 00:13:43 Yeah. Oh. Yeah, we're already nerdy. As Steve Gibson would say, our propeller hats are on. Yeah, yeah. Okay. So it's actually using IOC. IOC is a pattern.
Starting point is 00:13:55 And I'm a big, big fan of IOC as a pattern, not necessarily a huge fan of IOC as an IOC container. But AOP, yeah, it's kind of there. Yeah, that's one thing I noticed. I've been messing around with NINJECT a lot, particularly on solid tacto, is that the aspect-oriented programming frameworks, they feel like that. They've got that same kind of feel where you're dealing with a proxy object. And so they feel like they're in the same category to me.
Starting point is 00:14:23 Well, it's the proxy pattern. There you go. So let's get into this. As the AOP frameworks usually fall into one of two categories, there's the interception style and the injection style or aisle weaving type libraries. So dynamic proxy would be a big one in the in the interception category post sharp would be a very popular one in the uh aisle weaving
Starting point is 00:14:53 uh cat in camp so when you say aisle weaving you don't mean it's like changing my il do you uh yes i do in fact so okay yeah so so let's get into that. Black magic. Yeah, it's a post-compile step that will take your IL. It'll find where you have your aspects called in. It'll instantiate them, serialize them, and put them back into that modified IL. And that works? And somehow it does work. It's crazy. I have a hard enough time doing things the normal
Starting point is 00:15:27 way. Instead of going after the already compiled code. That's a really cool way of doing things though. Yeah. And there's really about three different types of ways of doing this. You have your attributes, which you can decorate. You have the configuration,
Starting point is 00:15:44 which is typically done through like uh you know config files xml files and that kind of thing and then there's your inline type aspects which we'll be talking about here in just a little bit so as i mentioned in the aisle weaving you know post sharp is one example in the in the java world aspect j the cons or let's start with the pros why don't we be positive about this? So the pros of doing the IL weaving would be that it's less intrusive, right? You don't necessarily have to have the source in order to apply an aspect to it. That's bizarre.
Starting point is 00:16:16 Yeah, but it's cool though, right? You could just apply an aspect to somebody else's code. This sounds like something that you were wanting to do back when we were talking about interfaces before, applying an interface to somebody else's code. Oh, yeah, that's very cool. I have to think about that. I have to chew on that one some more. That's cool, though.
Starting point is 00:16:34 So I could take a third-party library and I could add logging around the method calls. Exactly. That's really cool, including performance testing and stuff like that. I can see how long methods take to run, what methods are getting called, what order. That's really cool, including performance testing and stuff like that. I can see how long methods take to run, what methods are getting called, what order. That's really powerful stuff. So that's the advantage of doing that post-compile step. We'll get you, though.
Starting point is 00:16:53 It does make the debugging a little bit more difficult. It's not impossible, but it does make it more difficult. And specific to PostSharp, you can provide compile time validation as well as architectural validation. So if you want to make sure that your aspect, you know, a certain class is only used in a particular way or only used by classes named with a certain name or in a certain namespace, anything like that, you could actually create aspects to do that validation for you and throw compilation errors within Studio that the user would see. You could also throw warnings too if you wanted to, but you'd probably want to throw an error so that
Starting point is 00:17:32 no one would actually ignore it. Yeah, so there is this coming down side specific to PostSharp though. It's not all of the features are free. So the architectural constraints that i just mentioned that's not in the free version of post sharp so um and it's not cheap it's like 329 you know funky ease euros yeah funky about a money i think i got some extra funky ease yeah yeah it uh it it's not cheap and it's on a by seat uh license basis so um that but that's depending on which version you want it though right there is a free version in all fairness there is a free version of post sharp that can get you a lot of the way there
Starting point is 00:18:17 i still think the biggest thing for me is this that uh the debugging you know it seems a little scary but i haven't got a lot of experience with it, so I imagine they've worked out quite a few kinks over the years. I think AspectJ came out, first released in 2001, so this is not exactly a new concept. Yeah, PostSharp has got quite the following. There's actually a whole PostSharp Ultimate, I
Starting point is 00:18:38 believe, with open source aspects that are out there in the wild. Yeah, it seems like every conference I read about has some sort of post-sharp presentation. So that was it for the IL weaving type. Another kind of pattern for aspect-oriented programming is the interceptor pattern.
Starting point is 00:18:59 And this is where you have, like Michael mentioned earlier, a dynamic proxy or just a proxy that actually kind of wraps your calls and you utilize that to proxy those objects and methods. And what's nice about that is that you can debug it and there's less magic going on. So I think it's easier to read and easier to see what's going on. And I also think it's easier to test. And some common frameworks that implement this pattern are, for one, Aspectacular, which we're going to be talking a lot about coming up. Also, Castle Dynamic Proxy, Unity, Ninject. There are some downsides, though.
Starting point is 00:19:36 Performance is an issue. And it does require code changes. We mentioned not having to have the source for something like PostSharp, but this is a little bit different. We're actually going to be literally intercepting these calls and proxying them to another object. So that's a bit of a limitation. Some of these frameworks, particularly Castle Dynamic Proxy,
Starting point is 00:19:58 it's got some additional limitations like requiring virtual methods, which is a little gross. But, you know, pros and cons. Let's talk about Aspectacular. So, Vlad, why don't you give us a little bit of a rundown on it? Sure. The story of Aspectacular started a couple of years ago when I was implementing a run-on-mail business logic tier
Starting point is 00:20:25 that was based on anti-framework and was talking to SQL Server database. And with Lync, it's all beautiful. I'm really enjoying writing it because I really like Lync, just for the record, to put it out there. Wait, wait. Query syntax or Lambda?
Starting point is 00:20:44 I so hope you would not put me on the spot. You know what? I go through phases, and currently I'm in a Lambda phase. There you go. Okay, good. There you go. Right answer. Wait, wait.
Starting point is 00:20:58 No, this is not it. No, that was it. Okay, we're going to move on. I think my heart belongs to actual link syntax. Whoa, whoa, whoa. I didn't hear that. We're talking about how spectacular, man. Why are you bringing up link?
Starting point is 00:21:10 Stay on topic, guys. All right, all right. And I noticed that although the – I was looking at my code, and I was able to put most of the gross things, thank you, Joe, for putting planning in my mind, like, for example, instantiation of DB context. I put it away so my code looked clean. It would just call the method, the business logic method or the DAO method, and it would be very clean.
Starting point is 00:21:42 And then, of course, I still had to handle exceptions in the color tier, which was web application tier. And then later, I would have to add user audit trail logging on top of that. And after I added two of these, I thought, okay, now I have two, and that means that I don't want to keep throwing stuff on top of it. I need something better than that. So you don't use exceptions as a way to stop your program? Yeah. Well, I just wrap them in a cache and never show. That's how I write the perfect code that never has any errors in it.
Starting point is 00:22:20 That's right. I like what you said about there being two and that being kind of a smell to you. I like the joke that there are two numbers that matter to programmers, and those are one and many. That's about right. That's right. So when it was just try and catch around my business logic call, I could tolerate that. And I don't know, maybe there are still good uses for that or good justifications for that pattern. But once I started throwing additional stuff around it, I realized that, okay, I need to start thinking about that this is truly a cross-cutting concern.
Starting point is 00:22:53 And that's just a slightly different mindset because when we look at our code and we see that something needs to be wrapped around this piece of code, we just start wrapping around that piece of code and We just start wrapping around that piece of code, and we start doing it all over, and that's essentially a code stink right there, and it's an anti-pattern. And the answer to this is aspect-oriented approach to this, which means that aspect-oriented approach
Starting point is 00:23:22 allows us to throw in additional functionality, auxiliary functionality on top of existing calls to a business logic. But, okay, so let me stop you there, though. So there were already some aspect libraries out there, though. What was different about yours? Like, where did you see the need to – you saw that there was some void out there that needed to be filled. You mean besides not wanting to learn what other people did and rather do it myself?
Starting point is 00:23:48 Right. Okay. I was kind of hoping there might be some other reason. Yes, there were some other reasons. I just wanted to create a very simple AOP framework that is very friendly to feature function developers or to mid-level developers. I wanted to create something that could be used by architects to just put it as a pattern
Starting point is 00:24:14 and that any mid-level developers could easily pick up on that and just follow the pattern. So that was one thing why I felt that existing framework are either too complex or maybe a little bit too simplistic or maybe not ready out of the box to do that. Another reason was I really wanted to use LingQ and make it LingQ-friendly and to some extent even LingQ-centric. And I felt that there is no such framework that is pretty much link-centric. So I come up with my own. I wrote it fairly quickly.
Starting point is 00:24:51 First time, like about a year ago, I'd done something similar to that, but it was first time, first cut, not terribly clean. So this time around, just around Thanksgiving vacation, spending time with my family, and also sneak away a little bit. I think you spent more time with your computer. But my family was around, so I think it's common. I was in a public area. I was programming at the kitchen counter, so everyone could still see me.
Starting point is 00:25:28 And that's how I started uh how i started a spectacular and uh what i wanted to do is just make it relatively simple make it link centric and make sure that the the most important feature i think in a spectacular is that uh it can intercept any any method not just virtual, not just instance, but also certain methods. Yeah, so I was going to ask, is it an interceptor or injection? It's definitely... Weaving or runtime?
Starting point is 00:25:53 It's runtime. It's interception. So you supply your method as an anonymous delegate, or to be more specific, as anonymous delegate expression three. So that sounds fancy, but when I look at it, it basically just looks like
Starting point is 00:26:14 kind of a standard Lambda call to me, right? It is, yes. It's just a standard Lambda call, and that's all there is to it. So essentially, instead of calling like object.method, you say object.getProxy.method. Or for a static situation, for a static method,
Starting point is 00:26:34 you will call aap.invoke, and then you basically call the lambda on a static method. So this makes it sound like the aspects are applied at a more granular level, though. Yeah, you actually get more control of where and when your aspects are applied. So in some frameworks, for example, when you use IL injection for your aspects, imagine a few methods that call each other, and those few methods are all augmented by aspects. You will see the
Starting point is 00:27:10 aspects for outer method calls, then you will see aspects called for the inner method. But in Aspectacular, you can apply it just, for example, to the very top call, and everything inside will not have aspects applied to them.
Starting point is 00:27:29 Yeah, I really like that, actually. I was reading a little bit about PostSharp and how it's got kind of like in the middle of a method, a way you can do some injection there. And I thought that was pretty weird, because I feel like if you're injecting into the middle of a method, then maybe that method's too big. And one of the interesting things, too, that I liked,
Starting point is 00:27:47 and I can't remember going through all these things, but in Aspectacular, you can call a method and apply the aspects that you want at the time that you call it. It's very explicit. Whereas a lot of the other frameworks, you basically say that this method gets these aspects and so no matter where it's called or a name space right and simply so wherever it's called they always use those same ones whereas in aspectacular one of the selling features to all of us when we were looking at it
Starting point is 00:28:15 was oh wow if i want to call um you know print person right now or get person right now i can i can say okay i want to log it here because there's a certain type of person using it but over here in this other space i don't want to log it because i don't care these people shouldn't have to be logged so you can literally throw in the aspects that you want in the place where you want to throw them in so you can change that up on the fly whereas a lot of the other frameworks are oh you're calling get person well you're going to get logging you're going to get this and you're going to get this, and you're going to get this. And that's what you get.
Starting point is 00:28:47 And that's essentially the main differentiator, I think, between the IL weaving proxies like PostSharp and dynamic proxies like Aspectacular or Castle. It's because the application of aspects is very explicit. You tell when and where because you as a developer know why you're doing it there. So there is nothing implicit there. It gives you better control, and it also, I think, gives you a little bit more predictable execution path. I like that.
Starting point is 00:29:23 But you mentioned Castle, though. Castle is limited to virtual functions. That's correct. That's correct. They have different types of interception. They intercept virtual methods or method of classes that are subclassing the Marshall by ref.
Starting point is 00:29:40 But because Spectacular uses expression tree and expression tree in lieu of anonymous delegate, that's why I can facilitate the interception of just body of actually any method. Yeah, I think my two favorite things looking at Aspectacular is that, one, it is very explicit. I'm not a big fan of conventions-based stuff. Maybe I'm old school, but I like that I can see exactly what's happening. And also, I think a big part of having it be kind of explicit and set right there is that it's really easy to add to existing applications, brownfield applications. I can go in there.
Starting point is 00:30:21 I can add exactly what I want to. I don't have to worry about things getting applied when I don't want them to be or having to kind of reorganize my application so I can get some of those benefits like applying aspects to a whole namespace or whatever. I can use my application as it is, kind of poke these little holes through and refactor away. Yeah, essentially, yep, yep. That's exactly where the value comes from because if you simply start calling your business logic or DAO methods or web service methods through a spectacular proxy, you don't even need to add any aspects up front. You don't need to think about them right now.
Starting point is 00:30:57 You just start this pattern. Make sure that you wrap all your inter-tier calls into the AOP proxy. And you can think of everything else later when the boss comes yelling at you that it's slow or you need to log exception or you need to do audit trail or you need to retry or so on and so forth. You can start adding it. And creating aspects is also exceedingly simple. Yeah, and you mentioned creating aspects, but it looks like you've also got a lot of really nice built-in aspects that kind of come along with the project.
Starting point is 00:31:30 Can you talk a little bit about some of those? Yeah, absolutely. The Espectacle framework is coming with more than a handful aspects out of the box. It has, if you guys just care to clone the aspect tag from GitHub, you will see in the aspects folder, you'll see a whole bunch of things that have to do with transaction. For example, when you wrap your anti-framework call, you can, for example, dump the T-SQL code that this anti-framework query or link query will be translated to. You can do retries.
Starting point is 00:32:15 You can do output of logging to debug or to trace. So a whole bunch of things are already there. Caching is done in a pretty decent manner I think. It's done on a fair amount of depth Claims authentication for example if you have a web application and you're calling
Starting point is 00:32:35 anti-framework or you call any kind of DAO web service and you need to do authorization on the business logic which is another pattern that is easily implemented and enabled by AOP. I already have an aspect that will do authorization. Essentially, you just throw a few attributes on top of your method that you want to authorize
Starting point is 00:32:55 and tell them, okay, I want these user roles to be required for this method to be called. And all you need at that point is your principle and your identity being flown in in a manner that is just simply supported by a.NET framework. Yeah, that's incredibly powerful because if you think about how it's typically done on pages, I mean, talk about the additional code smell that you generally see thrown on top of a page. Hey, is he this? Is he this? Is he this? Does he have access to this? Being able to put in that authentication or authorization at that level is beautiful because now you're just basically passing in a few additional aspects, and it's easy. Yeah, in most cases, when you see a pretty well-done authorization, the best thing I saw so far is applying authorization attributes on the MVC controller in ASP.NET.
Starting point is 00:33:55 It's already a pretty good start, but if you want a second line of defense, if you want authorization on your business logic, that's where IOP is really a great thing to have because it can be done in a very declarative way and a very clean way. And I like that a lot for testing too because now I can test my security and my business logic in isolation.
Starting point is 00:34:15 And I can make changes to them in isolation without having to refactor or rejigger stuff. Yeah, absolutely. If you, for example, if you imagine that your caller tiers, like web application tier or testing tier or your web service tier, have different authentication
Starting point is 00:34:32 and authorization mechanisms, then when you call the business logic, you may want different types of authorization to take place before you do that, and it would be very hard and messy to do it straight in the code, and very easy to do it with A be very hard and messy to do it straight in the code and very easy to do it with AOP
Starting point is 00:34:47 and even easier to do it with Aspectacular because Aspectacular allows you to change the set of aspects you throw on top of the business logic method when and where you do that. So one of the key points and key design goals for Aspectacular was ability to apply different set of aspects depending on what your color tier is.
Starting point is 00:35:09 Because they usually will have different, like, for example, testing and web service tier. So just so everybody understands how big that is, he's basically saying you've got a function out there or a method out there that does something important, you can call that. You don't have to create multiple different versions of that method to handle the different authorizations at that time. All you have to do is throw in the aspect that you need at that time for that various authorization. So if you have a customer service agent versus a salesperson, right, the customer service agent should have more access potentially to something, and that sales rep would have less.
Starting point is 00:35:45 But you can call that same method now and just throw in the different aspects, and you're not writing any more code. You're just passing in the aspect that you need for that authorization. So that's fantastic. I mean, that reduces your footprint and your complexity greatly now. In the second version of Aspect Tech, one aspect that I'm going to add there is the aspect that changes
Starting point is 00:36:09 the attributes on the T-SQL command when you execute it. It throws a few of those set Aritha board set and null plus null equals null kind of things. Those attributes that execute the same query much faster
Starting point is 00:36:28 in SQL Management Studio compared to if you time the same function call from your application, usually you'll launch that. It will go much slower in your application compared to Visual Studio. And then if you start searching why, you see that they have these fancy attributes. And imagine you've already written the entire business logic tier
Starting point is 00:36:49 that doesn't do that. How do you just inject there? Without aspects, very difficult. You inject with aspects, your performance goes twice as fast now. So are you talking about on the actual SQL call, you'll have a pre-SQL script that you can have it run and then a post-SQL script? At this point, it's just pre-SQL script.
Starting point is 00:37:11 Okay, well, fair enough. All right, so there's part of the wish list. I think Alan's got some scope creep coming for you. I'm definitely a fan of that kind of stuff. Actually, I already thought about POST as well because you know what else is cool? I was talking with a coworker of mine a year ago and when I was just excited about AOP
Starting point is 00:37:32 and all this stuff, it kind of opened my eyes how cool it is. And I told him, can you imagine what you can do with aspects? I told him, you can create an aspect that will analyze the execution plan of your T-SQL and look for things like table scans, for example. You can throw a log where you'll say,
Starting point is 00:37:54 okay, these bunch of queries have table scans, and that's why they suck. This is my kind of programmer right here. Why? Because he loves SQL. No, I didn't say that. so so okay well he's aware of sequel he's not afraid of it right right yeah so so then uh you you mentioned like how excited you got um you know when you're first getting into aop now that you have gotten into it and you you've created this project like what's your perspective of it since has it changed anything he's like
Starting point is 00:38:23 has that love affair kind of dwindled away now that it's become more work since you've gotten into the project? No, no, I use it and proselytize it with being like a new foreign convert into this. I don't understand why not everyone is rewriting their business logic and dull tears with that as we speak
Starting point is 00:38:46 because I think there is no justification for not having it. And if anybody doesn't know what a DAO tier is, he's talking about the data access layer. Yeah, I'm sorry for all the TLAs. I'm sorry, that was the EFGs. And then the BALs are your business access layer. So yeah, I don't know if anybody's pointed any of that out, but I'm sure that we have some people that probably are a little bit newer to this,
Starting point is 00:39:09 so hopefully that helps out a little bit. So, okay, I want to get started with that spectacular. What do I need to do? What's that process look like? Well, it's very simple. You just add the spectacular either as a NuGet package or as a submodule if you use Git. You can pull it from GitHub, just search for Aspectacular, and you include it in your project. And then once you add the reference to Aspectacular, all you need to do is add it as a using namespace.
Starting point is 00:39:41 It's just Aspectacular, nothing else. Once you edit a Spectacular using namespace, you can just start using it. And in order to use it for a static method, you just say aop.invoke, and then you pass your method that you want to get intercepted as a lambda. And if you have a instance method that needs to be intercepted, you say
Starting point is 00:40:06 you instantiate the instance of the object, and then you call instance.getProxy .invoke and pass the lambda of the method you want to intercept. And finally, another kind of bonus is
Starting point is 00:40:21 if your method is an instance method of the class that is IDisposable, you can actually implement the IDisposable instantiation and disposing in just one shot. For example, that's very useful for anti-framework. DB context. That's something I really cannot get my OCD past that. I can dig that. Yeah.
Starting point is 00:40:47 Having to instantiate DB context and then get rid of it, even through using curly braces, is still too much for me. I don't want to do that. So what's possible with spectacular is instantiation, like implicit instantiation and destruction, disposing of iDisposable objects and still calling a method on that. Do you know how many hours of my life I've lost
Starting point is 00:41:14 trying to figure out where to put my DB context? Yeah, that can turn in a holy war, brother against brother, where do you instantiate the DB context, how long you let it live. I prefer to instantiate and kill it instantly, where I call it, by the caller tier. All right, so tell me this, though, because one of the things that we spoke about,
Starting point is 00:41:38 actually shortly after I met you, that kind of opened my eyes to iQueryable, was the fact that you can instantiate a DB context. And if you have that thing available at the time that you call, let's say, a method that says get people, and then you have another one that says get orders, but then you want to join those two things together in the standard way, as Joe pointed out a second ago, if you try and instantiate your DB context in the get people and then you return the IQueryable, it's done. You can't use that anymore. And then when you say get orders,
Starting point is 00:42:10 even though you have two IQueryables, you can't join them together because the DB context is closed and it's going to fail. So do you have a way of being able to say, hey, I want my DB context. Now I want to call two methods and join them together.
Starting point is 00:42:25 Do you have a way to wrap that? Yeah, to me, there are two ways to do it. One way that I usually practice is to write all the DAO and BL method as instant method of DB context itself. Thankfully, DB context and object context are partial classes. So you can create your own file, and you can start stashing your DAO and BL methods right there as instance methods.
Starting point is 00:42:49 And to improve on that, you also return IQueryables. Whenever you read data, I'm not talking about updating and saving and searching, but when you read data, always return IQueryable, no matter what, return IQueryable, because that allows you to call and join on that. data, always return iQueryable, no matter what, return iQueryable, because that allows you to call and join on it. It's just important to remember that iQueryable is not the result set. It's still just a statement. All right, but using your aspect, how would you go about doing that?
Starting point is 00:43:18 So if you call something that's going to instantiate your DB context and then you want to call these two different methods, is there a way to chain those before instantiate your DB context and then you want to call these two different methods, is there a way to chain those before closing out your DB context? It's important to know that when you call a spectacular, you can only pass one single method to it.
Starting point is 00:43:37 You cannot pass curly braces and 15 methods inside. It should be actual method signature. So when you do that, it means that your business logic that you want to augment through inside. It should be actual method signature. So, when you do that, it means that your business logic that you want to augment through AOP will need to go into a single method, which is already a pretty good pattern.
Starting point is 00:43:54 We're just enforcing it. Once you wrap your DAL-OBL logic into a single method, that method should stay an instant method of the DB context if you just have one database. There are more complex cases that are also supported by X Spectacular. For example, if you have multiple databases, if you have OLTP and you have your warehouse database,
Starting point is 00:44:17 which is pretty common, there is another class that wraps that around. So you can create instant methods that go to two databases. And when you implement that method, both connections are already available to you. Nice. Yeah. But the pattern that works the best with Aspectacular is this.
Starting point is 00:44:37 Implement your anti-frave work, Dell and BL methods as instance, or at the very least, implement them as extension methods that take dbContext that is already created. There is a special subclass for the proxy
Starting point is 00:44:56 that deals specifically with dbContext and objectContext that will instantiate them, and it will allow you to call your method that returns as a spectacular. So instead of doing something like instance of dbcontext.getproxy.callyourmethod.toList, you can say create the proxy for dbcontext. And then instead of call.invoke you say
Starting point is 00:45:26 .list or.single and you pass a function as a parameter that returns iQueryable. I know somebody who's a fan of that already. Yeah, you had me at i. Wait, I thought you hated it they started with i.
Starting point is 00:45:44 It's in the middle. Don't get me started. But he likes the list feature. Well, he'll convert that to an enumerable. Yeah, I like that you're pitching iQueryable because I'm often struggling with whether to return an iEnumerable to iList. So just iQueryable and I can stop thinking about it, right? Yeah, basically I think that everything that requires wire trapping
Starting point is 00:46:07 should be done in the color tier, not in the tier where you actually implement that. So it should be postponed to the very last possible minute when you actually start pulling data out of the database because this way you reduce the number of round trips and you have an opportunity of generating very ugly T way you reduce the number of round trips and you can generate, you have an opportunity of generating very ugly T-SQL in the process. Basically the last responsible
Starting point is 00:46:30 moment. Yeah, exactly. And by the way, same goes for calling the save changes. A spectacular class that is specifically designed for working with anti-framework will call save changes for you.
Starting point is 00:46:46 So you don't have to do save changes after it inserts, deletes, updates. You still may do that if you absolutely have to. But again, that's the same as tripping the wire. It should be done by the caller, and save changes the same way, I think.
Starting point is 00:47:02 So if I want to create my own aspect seizing aspectacular, So if I want to create my own AspectSeizing AspectHackler, what do I need to do? Simply a subclass AspectClass that's already in the AspectHackler. AspectClass has seven virtual methods that represent different stages of life in the function call. So when you mentioned the pre and post before with the SQL, so there would be like a pre-step and a post-step
Starting point is 00:47:26 that would be one of those seven? Exactly, yeah. So it's basically, they can be roughly split into groups that happen before and after. And some of them happen only when error exception occurs, and some of them happen in either case, and some of them happen only if successful call occurs. Seven's a lot. Seven's a lot.
Starting point is 00:47:46 That's a lot of interception points. I started with like four, and then as I kept working on it and trying to, for example, when you try to implement fairly hairy logic, for example, like retries, well, and then you get into something, do I allow retries only on exception, or do I also allow retries
Starting point is 00:48:05 on successes? And that requires different type of interception. And one thing I really like, I'm actually looking at the interface, I aspect right now, one of my favorite things about Glide's code is it's very explicit. So when you look at these interception
Starting point is 00:48:21 points, it's very clear when it runs and exactly what it's doing. I mean, he's got names in here like Step 1, Before Resolving Instance. Yeah, I was going to run through a couple of these names just to make it clear to everybody. I was going to ignore the Step 1 parts. But yeah, so you have Before Resolving Instance, Before Trying Method Exec, Before Massaging Returned Result, After Successful Call Completion. That's an optional one. instance before trying method exec before massaging returned result after a successful call completion that's an optional one yeah so that was i was going to call that come back to
Starting point is 00:48:51 that as a question but after catching method exec exception finally after method execution after instance cleanup and step seven after everything said and done yeah i love that's my favorite method name everything's said and done and that method usually only there was a method like a step eight at the end of the day yeah wow alan should create a fork of that yeah yeah i got it so so okay so joe joe handed on one that i was i was wanting to bring up because some of these uh steps in the uh interface stick um contract to bring up because some of these steps in the interface contract here, some of them are marked as optional in the name of the method. But aren't they really all, you know...
Starting point is 00:49:33 They're all kind of optional, right? Well, yeah, optional in this context means that they may not be called depending on the execution path. So optional are not guaranteed to be called. Also, technically... So an example there then to illustrate what Vlad's talking about is one of them, as you heard me say, was after catching a method exec exception.
Starting point is 00:49:57 Well, if it doesn't throw an exception, then there's not going to be a call to that method. Exactly. Yeah, same goes for a successful call completion because you may not get that either. Whoa, whoa, whoa, whoa, whoa. Oh, well, it could be returning void or something, right? Or it could be a void.
Starting point is 00:50:13 No, it could be an exception, and then you don't get success. Oh, he's saying it was a success. Right, fair enough. And that's why I'm like saying, whoa, whoa, whoa, my code. Come on now. Technically, step one also should be called optional because when you call static method, there is no resolving of the instance. Come on now. Technically, step one should be called optional because when you call static method, there is no resolving of the instance.
Starting point is 00:50:28 Okay, yeah. All the other steps, they might do nothing, but they all get called. Pretty much, yeah. Step two is probably the most popular because that's right before you call the method. And step five, finally, after method execution, whether that was a success or failure,
Starting point is 00:50:44 that is a fairly useful one. And finally, step seven, after everything execution, whether that was a success or failure, that is a fairly useful one. And finally, step seven, after everything is said and done, is a very good place to ship your call log. So basically, for anyone who's following along there that's really big into the design patterns, this is a template pattern that's being used here deep within the bowels of the spectacular framework and you're gonna i didn't know i didn't know that i'm so fancy i'll put i'm putting it on my resume i have i have the template pattern you're gonna you know you the caller can implement the this ask this uh interface and provide in the hooks that it may or may not call. So Vlad's defined the skeleton here and it's up to you to fill it in where
Starting point is 00:51:28 you need it. If you clone the project from GitHub and look at the aspect folder, you will find a file called simple stock aspects. It has
Starting point is 00:51:42 four different aspects implemented. They are not dummy or example aspects. They are real useful aspects and like for these classes only took about 100 lines of code all together to implement them. So you can definitely see how different aspects are implemented and you can look
Starting point is 00:52:00 at a whole bunch of aspects that are already there to see, to follow the pattern, to implement them. One thing I would like to mention is that when you develop your own aspect, you should not be logging to any specific logger like trace or debug or log for net or event log or anything like that. Proxy and aspects allow you to log into the call context.
Starting point is 00:52:27 So your method, when it's intercepted, has access like you have access to HTTP context, right? Whenever you are in HTTP request handling, you have this access to HTTP context. It will have something in it that you can work with. The same goes for logging. When you are inside the intercepted method, you can log to the proxy. Proxy has a collection of log items that grows as you log.
Starting point is 00:52:56 It doesn't go into any specific output stream like std debug or std out, anything like that, std error. It just gets accumulated in the collection, and then the collection later can be taken by another aspect and either thrown into the output in your test context, in your log for net, and whatnot. That's really powerful. I mean, it takes away the need to log specifically different ways
Starting point is 00:53:24 in your aspects, right? You can get it after the fact is basically what you're saying. Yeah, absolutely. And this is kind of a design flaw that I may fix at some point because really most of your aspects don't either have to write to the log collection or to read from it to send it to somewhere for looking at it. But it's not implemented that way in the spectacular. Well, so you kind of hit on something that we were wanting to get to. We've already mentioned this is hosted on GitHub already,
Starting point is 00:53:56 but so if others want to contribute to this, what kind of suggestions do you have? Is there already a list that you're maintaining of issues that you want to get to, like what you just mentioned? Well, I'm not terribly disciplined. Right. No, I'm not. I've seen your variable names. I write the web server.
Starting point is 00:54:22 But no, he's not disciplined at all. No, I'm not very disciplined in making plans and following the plans i i i'm kind of very i'm driven by the spur of the moment thoughts so uh that may make collaboration a little harder but i i certainly encourage sending me pull requests by all means please take a look at at how I do things so it's more or less in the same vein, so it would be easier for me to review and merge. I will appreciate useful aspects a lot because that's where the value for the community out there will probably come the most. Well, I feel like we should also mention, too, though, that if people are going to contribute, like, what
Starting point is 00:55:05 license does this fall under? Oh, it's MIT. It's, like, do-whatever kind of license. Yeah, that's... With attribution. That's absolutely a huge thing. Also, I do want to point out, because we had a discussion on this previously, is Vlad was worried about getting this out there to the world because he hasn't documented it
Starting point is 00:55:21 properly and all that kind of stuff. I will say, like, if you just open up this solution and you take a look, there's unit tests and that kind of stuff. And if you pull it from GitHub, you'll get all that. You can actually see really easy ways of going about doing this. So it's almost self-documenting. And I will say, like, he has done a tremendous job on commenting the code as well. So as Michael just pointed out a minute ago with the steps and the aspects, I mean, they're named in a way that you understand,
Starting point is 00:55:52 but to even take it a step further, he has the proper documentation comments within the code. So he has his summaries and all that. So while it may not have the official documentation and all that stuff yet, it's actually done in a way to where pretty much any competent programmer, even at a fairly novice level, can pick this up and run with it.
Starting point is 00:56:12 But we should also mention, too, I don't know if this has been mentioned yet, because we've said several times that it's available on GitHub, but if you wanted it as a NuGet package, it is available as a NuGet package as well. And speaking of contribution, documentation is also a contribution.
Starting point is 00:56:28 So I'm sure if you want to write some... If somebody is going to add a Doxygen generator into the solution, oh yes. We'll be merged first. That takes priority. Yeah, that's a great way to kind of learn the project
Starting point is 00:56:44 too. So go through, write some stuff, and there you go. You've contributed to open source. Yeah, absolutely, yeah. And thank you, Alan, for pointing it out, because it kind of almost departed from my mind that the unit test is probably the best way to get into it, because it will show you the basics of how it's done, and it's really easy to do
Starting point is 00:57:06 and he's got several in there i think there were what 20 no 40 41 tests passed when i ran this so um he's got he's got examples in there of real world type stuff this isn't just hey you can call this code these these are things that are using the adventure works database so if you're going to be working on a project that's using a database, then you can actually see real-world examples of how this would work. So definitely if you plan on using this, before you go asking a ton of questions and all that, at least poke into the unit test and take a look around.
Starting point is 00:57:39 Well, speaking of that, some of the unit tests that are in there are performance-minded type tests, like how long did this SQL call call? What's your thoughts on from a performance point of view? So you've written Aspectacular, right? But then we mentioned like Postsharp, for example, the IL weaving. So there's already, you know, this is another holy war. So like, well, from a performance point of view, which path to go down. Well, the specific design goal for me here was to enable easier creation of business logic, web service calls, and data access calls.
Starting point is 00:58:15 And those are relatively slow. I chose the expression tree parsing as the viewing mechanism. It's relatively slow because it's parsing compilation of the expression tree, although it has some tricks to make it faster. So that is relatively slow, but still, if you, I had the overhead calculation for a typical, even for a very fast database
Starting point is 00:58:56 that is running locally and running on SSD and has small tables, still the overhead may be like 5%. The only caveat here is if you start logging the actual values of the method that were passed to you, those are going through the evaluation process, and that evaluation process involves reflection. All right, so what kind of hit do you take on the performance there?
Starting point is 00:59:26 It really depends on the number of the parameters because it's directly proportional to the number of parameters. So it can go to like a few milliseconds basically, but it's still something. It's not nothing. But in a great scale of things, it's a very, very modest hit. And just to be clear, I mean, if you're going to go through and just automatically dump all your parameter values out,
Starting point is 00:59:49 you should be aware that you're going to take a hit anyways because that's not something you typically do anyways. Yeah, but think about it. Like, expression-free compilation is still something that occurs when you do the conversion to link of yours. Sorry, conversion of link to T-SQL, for example, right? So those relatively slow things that happen in your software, in your program, they still take place.
Starting point is 01:00:16 And I just thought that it's a pretty small price to pay for making it convenient. And as I said, I was not really trying to create absolute general purpose type of AOP framework. I was trying to make life simpler for those who do this day-to-day writing of business logic, who call web service and so on. Well, I mean, let's also think about it from this perspective too, right? How much does it cost to upgrade a server
Starting point is 01:00:50 versus how much does it cost to have a programmer going and copying and pasting code all over the place to finally create this spaghetti code, only to have to manage it a year down the road? Yeah, I seriously doubt that AOP is going to be what kills your application. Right. So, again, he's being very honest in his
Starting point is 01:01:06 description of the actual performance hit that it takes but at the end of the day a five percent hit on milliseconds is ridiculous right like it's it's almost nothing so you know just just take it in you know in context to what he's speaking about so and he's actually got you know tests set up in there specifically for measuring performance so you can take these tests run it and see what you get yeah and i mean it's funny i know we sound kind of like cheerleaders for this but it's it's he's done such a thorough and good job with it that it's i mean that's why we had him on the show because he really has put a lot of thought and effort into this like the caching the caching mechanism came up because you know outlaw was like well like the caching the caching mechanism came up because
Starting point is 01:01:45 you know outlaw was like well what about caching he's like you know what let's we'll add it so i mean it's it's one of those things where he's really taking a heart all this stuff and and i mean has just done a killer job so um you know i'll quit my hoorah thing and i want to come back to uh thank you very much i want to come back to testing. Thank you very much, Colin. I want to come back to testing again real quick because I've got this kind of unhealthy fascination with unit testing. Is there a such thing? I don't think so. I was just being humble.
Starting point is 01:02:19 But it seems to me like this is a really great project where you really need unit testing in order to see that this stuff's working. I mean, I can't imagine what it'd be like to try and work and create aspects if you weren't able to test them so easily. on Korean, German, Russian, Windows or Windows XP 7, Vista, 32, 64, in every imaginable scenario. And if you want it to live and not become the thing that destroys your family and your life and your sleep, you need to make it right. So actually this one was not that terrible. This project was relatively easy.
Starting point is 01:03:06 Right. Because he does it for fun. Yep. It is fun. Right. Why do we all do this? For money? Come on.
Starting point is 01:03:16 I know I write a web server like once a day, just to pass the time. But back to Joe's point though, so like the unit test, we haven't done an episode on it yet but we plan on in the future uh these are great examples of how to write your unit test oh this is not a great example it's just in i think it's an example because it does not do the the um the whole thing the 100 coverage coverage at all. But they're...
Starting point is 01:03:46 So this is an example if you're not going to do 100% coverage, but you want to get some tests done. Right. Yeah, I can't see how you would work on it without being able to test. Are you going to create a little console app to test out a new aspect or an intersection point? No, of course not. Yeah, it's totally impractical. Right. Yeah,
Starting point is 01:04:02 unit tests are a great thing because it's a relatively closed system. It does not rely on a huge ecosystem that needs to be in place in order to be tested. So unit tests, they provide... I mean, you don't need really an integration test here because all these pieces are true units. If you test them through unit tests,
Starting point is 01:04:22 you're pretty much golden. Your quality is going to be there. That's great. So speaking of good practices, I wanted to mention something that I ran across that's definitely not a good practice. As soon as I got my hands on Aspectacular, the first thing I tried to do was something that's pretty inappropriate for Aspect-oriented programming.
Starting point is 01:04:43 And what I was trying to do is basically sanitize some output I was being lazy and I talked to Vlad about this and and uh you convinced me it wasn't a great idea and I wanted to see what you thought about like basically other way other ways that you could misuse AOP and if you've seen or heard anyone ask for maybe an aspect that was just not a great idea so So we're talking about sanitized output. We're talking about taking SQL results and trying to turn it into an HTML table or something. Well, for me, I wanted to chop off some numbers off a decimal. I'm like, I'm tired of dealing with this rounding crap.
Starting point is 01:05:16 Just two digits right here. Keep it on my BL. But you could do it. So dirty uses of AOP is the question on the table. Yes. I got it working. Well, once you get in the mindset of, oh, I can change what was returned to me because, yeah. And even with a Spectacular, you are able of doing that. For example, when I return the IQueryable and my proxy all of a sudden returns the list to you instead of IQueryable, something happens inside, right?
Starting point is 01:05:50 So you know that it's possible to actually play around a little with what was returned to you by the function that was called. So, yeah, you can go ahead and start tweaking the return result, but that is a bad idea. Yeah, you're really messing with your business logic at that point. And you're supposed to be decorating. You're supposed to be adding these aspects. You're not supposed to be really modifying the results. Exactly. And that's precisely what I told Joe when he asked me,
Starting point is 01:06:20 is it a good thing? And I said, it looks like it's business logic. So business logic belongs in the business logic, not in Aspect. Aspect is just... It's a bolt-on. Yeah, it's total bolt-on. It's something that you... It's an afterthought, but it's not...
Starting point is 01:06:36 Your business logic should not be an afterthought. Right. And ever since that conversation, I've been trying to figure out, like, what else I can cheat on? How else can this be misused? Actually, another thing, we talked about this a bit, but I just wanted to mention something else that I tried to misuse
Starting point is 01:06:55 about the framework is I wanted to log something to a database. The first thing I did was write an aspect that would take in the arguments and would write it to the database. And as Vlad mentioned, the log collection, I wanted to see if I could kind of put it in my own words, and you can correct me if I'm wrong,
Starting point is 01:07:13 but it's basically a collection of strings that I can throw my data into, and then later I can actually write something to pluck the relevant data out and do the logging from there. That way, rather than this being something that's specific to writing to the database, I can write to the database as well as log it to disk or do something else with that information. Yeah, exactly. When the proxy calls the method that needs to be intercepted and augmented, the proxy itself keeps a collection of log items,
Starting point is 01:07:46 and that collection can be populated through methods. So proxy itself puts data in this collection. Aspects can put data in that collection. Collected by key value. So I've got a key there that I can use to kind of pull this data out. Yeah, it's key value, but it has two additional attributes on it. It tracks who put it there, like what method proxy or aspect. And it also has the traditional warning info and error attribute on top of that. So when you create an aspect that needs to, for example, report only errors, it can just pull errors. But it also has keys. For example, you'd be able to select only records that interest you and send them to either a debug or a log for net or whatever else. Yeah, so when he was talking about the log shipping earlier,
Starting point is 01:08:38 all that means is after you've gathered all the stuff that came out of the aspect, then you ship it to whether the database or a log file or wherever you want to put it. But that's what he was talking about. He has all the stuff, but then after you get it all back, you determine where you want to put it. Don't put it in your aspects because you don't really want to create an aspect called log to database and then another one log to file
Starting point is 01:08:59 and then another one log to whatever. Absolutely. You just want the information out of it, and then you can decide what you want to do with it later, and then you can swap it out easy. Absolutely. You just want the information out of it, and then you can decide what you want to do with it later, and then you can swap it out easy. Absolutely. If you look at stock aspects that are already implemented, for example, there are
Starting point is 01:09:14 a couple of them. One is taking the log and putting it in a debug output, and another one is putting it in trace output. So you can take a look and see how they're done. It's just a few lines of code for each. And that gives you an idea how you can spit it out to LogFonet, how you can spit it out to Splunk,
Starting point is 01:09:31 or how to spit it out to Windows Event Log, for example. Very cool. I've got a question I just thought of now, and this is the dumb question, but this is the kind of stuff that I really get hung up on. So if I'm writing my own custom aspects for my application where do you think i should put those aspects like do you think i should have like a folder at the top level called aspects or you know should be should be his own project well aspects in in most cases well it's a tough one because it really depends how useful your aspect for other
Starting point is 01:10:02 tiers for other color tiers uh you probably if you come up with an aspect that is useful for multiple different tiers, you can put in some place where, maybe even the same place where your business logic is, I mean, the same project, maybe. But it's a good one. I don't have a perfect answer for that. Maybe if it's very specific to only a couple of classes, I could put it in that namespace right alongside. Yeah, maybe people who listen to this will come up with better ideas for that. Maybe if it's very specific to only a couple classes, I could put it in that namespace right alongside. Yeah, maybe people who listen to this will come up with better ideas for that, hopefully. Yeah, you can even
Starting point is 01:10:30 put it in just a standalone project that has a reference to it, and then you could use that, right? That's kind of weird if I only have two files in there. If you only have two, right, right. But you're already doing a solid program, so you already understand all that. I love lots of projects. Don't get me started. So, looking at the
Starting point is 01:10:46 Aspectacular when you pull it down, there's this one section called the Framework Core. Can you talk a little bit about that? What's in there? Yeah, it's a bunch of freebies and things that I like and need and all sorts of things that I think
Starting point is 01:11:01 are missing from the Mothership.NET framework. It's not really related to aspects in any way. It's just a whole bunch of convenience classes and types and converters. And, for example, ever since the extension methods have become a part of our lives, I thought, oh, there is no place for string.isEmpty or whitespace or null, something like that. It should be an extension method
Starting point is 01:11:31 because extension methods, unlike instance methods, allow you to deal with nulls properly, right? So you can pass this string something and that string something can be null, and you can still call an extension method on the string, for example, even if that string is null. So that's where lots of convenience methods come from. So there are tons of convenience methods for string, for type, for daytime. I created a type called range,
Starting point is 01:12:05 which I really miss from... That should have been in a.NET framework, in my opinion. So basically, this is the world according to Vlad. Exactly, yes. Things that should be there. If I was a benevolent dictator, that's what I would put in a.NET framework. This is like your toolbox.
Starting point is 01:12:21 You show up to work like, all right, I've got my utilities. Yeah, absolutely. Because when you go from one project to another and you need to do something like date range, how many times can you do that? That is the box that I'm traveling with. That's very cool. Maybe one day we'll see a separate project for just Vlad's tools. Yeah, maybe. Maybe one day we'll see a separate project for just Vlad's tools. Yeah, maybe.
Starting point is 01:12:50 It'll be Wave, World According to Vlad. Oh, wow. You're good. He's a marketing genius. There you go. See, I'm down with EFG, ABC, WAV, AOP. All right. I got all that since we're putting
Starting point is 01:13:05 that out there that's already we can we can claim copyright for that right under MIT free beer right
Starting point is 01:13:14 what was the beer one I want the beer one I picked the beer one there's a license there somewhere and that that really wraps it up for my questions
Starting point is 01:13:23 yeah that was that was speaking of licenses of beers did you guys know that someone is making Dove beer no really and they make it somewhere and ship it someplace else because in that there is some kind of loophole
Starting point is 01:13:39 that allows them to not to pay Simpson people for that so it's not Springfield Illinois apparently not I think it's not Springfield, Illinois? Apparently not. No, no, no. I think it's like made in Mexico and sold in Europe or the other way around, something like that. Springfield, Mexico?
Starting point is 01:13:52 Wow, man, lawyers. That's awesome. Yeah, so this has been quite the entertaining podcast, just learning about this madness that you've created here for us. And among other resources that we like, we'll be putting in the show notes the link to The Aspectacular, but it is available on GitHub, as we've mentioned, if you were to search for it.
Starting point is 01:14:17 But also in the same vein of Aspects, there's a great book that I liked that was called AOPN.net Practical Aspect Oriented Programming by Matthew Groves. It's a Manning publication, so you can get that as well as get the soft copies. You did use it?
Starting point is 01:14:35 I use that book a lot for inspiration and it didn't get me convinced to pick one of the two that were profiled there prominently, namely PostSharp and Dynamic Proxy. But it gave me the validation, the reaffirmation that there is still a place for my way of doing aspects, particularly to make it friendly to real Americans. As Vlad was mentioning, he does a great job of comparing, the author Matthew Gross does a great job of comparing functionality between the two,
Starting point is 01:15:28 and he does a very careful dance of not letting his his viewpoint of picking just the one he shows concepts in both so it was really good but cool and it is a manning publication so uh keep that in mind i know some people uh love and some people hate the covers of manning books so you know you've been warned you can't get the kindle like you have to buy the book and then they'll be like oh here's a code where you can download it and get the Kindle. Where it's like, I just want to buy the Kindle version. I don't want the paperback. I don't need any paper. It's Kindling for fire.
Starting point is 01:15:55 Also, one thing I want to mention, we talked a little bit about interception frameworks versus injection AOP frameworks. There's this guy, Kenneth Triers, who's got some excellent articles on the subject and he favors, um, interception frameworks as well, like as spectacular.
Starting point is 01:16:08 So we'll have a couple of links to some articles as he's written that are, that are much better spoken than I am. All right. So now let's, uh, wait, is there one more? Yeah.
Starting point is 01:16:19 Yeah. Yeah. There was a, Oh, look at that plural site. I feel like we've mentioned plural site, uh, every episode. It's fantastic's fantastic is it like 29 a month and all the videos like a buffet of tech knowledge yeah it really is if you if you've never heard of it you should go check it out
Starting point is 01:16:36 and we don't get any money for mentioning this it's just for your own benefit yeah it's it's almost like it's just an expense you know you just got to deal with it yeah or programmers who make good money get plural site think about it like this it would cost you less than one college course to get this thing for a year and you have access to seriously some of the best programmers in the world taking their time to teach you how to program like donald belcham who did a course on aspect-oriented programming specific to.NET, and we'll have the link to that course. So with that, let's get into the tips of the week here. So I found a really cool Chrome app that I like. It's available as an app and as an extension,
Starting point is 01:17:22 and it's called the Bulk URL Opener. If you're doing web development and you have a bunch of test URLs that you just want to be able to hit all at one time, all your different use cases, this is your guy. You can just throw them on there. You can set options
Starting point is 01:17:39 to open them up in a new window and have them all separate. It's fantastic to be able to test multiple use cases at one time. Test? Heck, I want to be able to hit one button and open up my news, my Reddit, my Reddit, maybe Slashdot. Well, that's fine.
Starting point is 01:17:56 And, of course, you know, like somebody's going to be like, oh, you should be doing unit tests. I don't know. Fine. These are more like for integration tests. I was going to open my coffee tests. Open my coffee suite. Open my morning sites. Yeah, okay, so fine.
Starting point is 01:18:12 All right, so my tip of the week is Web Essentials. It's a plug-in for Visual Studio. And if you do any kind of web development and you have to mess with JavaScript, CSS, all that kind of stuff, this is a must-have. You can do things like right-click a JavaScript file and have it minify it, and it'll track it. The CSS editor on it is absolutely fantastic.
Starting point is 01:18:32 I hate having to go look up different types of selector styles and all that kind of stuff. So it's all baked in, and they've got a ton of different features. And being that I do a lot of web UI type stuff, it is seriously one of my favorite plugins. So that's mine. Yep, and I wanted to mention actually a tip that I got out of the fantastic book, CLR via C Sharp. One thing I struggle with all the time is actually not using UNs more often. It drives me crazy that arrays take integers and not uints,
Starting point is 01:19:06 even though negative numbers are invalid. And this is the kind of thing that keeps me up at night. So I feel a little bit better about reading some quotes from the CLR via C Sharp book. And basically it kind of boils down to uints not being common CLS, which I'm totally blanking on what that stands for now, but it's basically the common language system. Sounds about right. So, you know, like certain languages like maybe F sharp or visual basic.net may not
Starting point is 01:19:32 have support for Uint and end up just converting them to ints. And also, you're just going to do less casting if you just stick with integers. So Uints are nice and, you know, believe me, I get it, but don't feel so bad if you end up breaking down and using integers. So UNs are nice and believe me, I get it. But don't feel so bad if you end up breaking down and using integers. And we've got a blog post that I wrote a couple years ago where I scraped the arguments from CLR via C Sharp.
Starting point is 01:19:55 Ever since UN have become second class citizens in.NET, I remember living in C++ universe and after migrating to.NET UNs almost like in no man's land. It's like it makes me sad. My OCD really suffers from that. Yeah, it's crazy.
Starting point is 01:20:13 Like an array, the index is an integer. Negative one is invalid. And my tip of the week, use AOP, would you? Excellent. Excellent tip of the week alright so with that we'll be putting the links in the show notes you'll be able to find on codingblocks.net
Starting point is 01:20:32 slash episode 9 again subscribe to us on iTunes, Stitcher and more using your favorite podcast app be sure to give us some reviews that helps us to help others find us so that they can enjoy these shows as well yep and contact us with a question or topic and leave your name and preferred method of shout out website twitter whatever
Starting point is 01:20:52 facebook and uh we'll mention you on the podcast get you some love out there and a review on itunes would be greatly appreciated and you might get multiple shout outs like across multiple podcasts who knows so uh i know there's some listeners out there and you guys get multiple shout outs like across multiple podcasts who knows so I know there's some listeners out there and you guys haven't gone in and read this yet so visit us at codingblocks.net where you can find show notes examples discussions and more and
Starting point is 01:21:16 specifically this one will be www.codingblocks.net episode 9 and make sure to send your feedback questions and rants to an email address to be set up. Comments at codingblocks.net and also come follow us on Twitter.
Starting point is 01:21:31 We are pretty chatty on Twitter. That would be at codingblocks. At codingblocks. Yep, so that wraps it. Thank you, Vlad, for joining us. Thank you guys for having me. It was enormous fun. Awesome, awesome. Yeah, this joining us. Thank you guys for having me. It was enormous fun. Awesome. Awesome. Yeah, this was awesome.
Starting point is 01:21:46 So, that's a wrap. Look, Vlad, at lunch today, you weren't there. This man lined up his french fries. Like, lined them up. Okay. And salted and peppered them. Like, lined them up like little soldiers or something. It was ridiculous.
Starting point is 01:22:13 I don't appreciate that we're recording this.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.