SlideShare uma empresa Scribd logo
1 de 13
Multi-Tenancy: Beyond the Whiteboard Chris Hefley, Bandit Software Blog: http://indomitablehef.com Email: indomitablehef@gmail.com Twitter: @indomitablehef
Multi-Tenancy
The Big Decision Database Per Tenant Schema Per Tenant Tenant Id per Row Tenant as Aggregate Root
Other Considerations The Url  app.com  		(salesforce.com) tenant.app.com  	(me.basecamphq.com) app.com/tenant 	(facebook.com/me) tenant.com  		(mynewyahoostore.com) Data access ORM Dynamic SQL Stored Procedures
Design Goals Agnostic Secure Maintainable
Design Patterns: Repository Domain Model public class Person {…} Repository (PersonRepository) repository.Find(PersonQuery q) {…return Person} repository.Remove(Person p) {} respostory.Add(new Person {…}) repository.ListByProject(Project p) {…return List<Person>} Data Access Layer dao.RetrieveOne(Dictionary<string,object> parameters) dao.Delete(person.Id)  dao.SaveOrUpdate(Person p) dao.RetrieveAll( Dictionary<string,object> parameters)
Repository as Boundary Your Application “Knows Nothing” Repository Effectively adds: “WHERE TenantId =“ To every set of criteria passed on to the data layer
Design Patterns: DI/IOC
Inversion of Control
Inversion of Control
First Benefit: Testing
But wait, there’s more!
SokMunkae Data Model Organization User Project Task

Mais conteúdo relacionado

Semelhante a Dev Link2009 Multi Tenancy Beyond The Whiteboard Chris Hefley

Building Social Enterprise with Ruby and Salesforce
Building Social Enterprise with Ruby and SalesforceBuilding Social Enterprise with Ruby and Salesforce
Building Social Enterprise with Ruby and SalesforceRaymond Gao
 
Elegant Rest Design Webinar
Elegant Rest Design WebinarElegant Rest Design Webinar
Elegant Rest Design WebinarStormpath
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web DevelopmentRobert J. Stein
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Oliver Gierke
 
External to DA, the OS X Way
External to DA, the OS X WayExternal to DA, the OS X Way
External to DA, the OS X WayStephan Borosh
 
Graphql + Symfony | Александр Демченко | CODEiD
Graphql + Symfony | Александр Демченко | CODEiDGraphql + Symfony | Александр Демченко | CODEiD
Graphql + Symfony | Александр Демченко | CODEiDCODEiD PHP Community
 
Basic of Big Data
Basic of Big Data Basic of Big Data
Basic of Big Data Amar kumar
 
Big data, just an introduction to Hadoop and Scripting Languages
Big data, just an introduction to Hadoop and Scripting LanguagesBig data, just an introduction to Hadoop and Scripting Languages
Big data, just an introduction to Hadoop and Scripting LanguagesCorley S.r.l.
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocratlinoj
 
Introduction to data science with H2O-Chicago
Introduction to data science with H2O-ChicagoIntroduction to data science with H2O-Chicago
Introduction to data science with H2O-ChicagoSri Ambati
 
Introduction to Data Science with H2O- Mountain View
Introduction to Data Science with H2O- Mountain ViewIntroduction to Data Science with H2O- Mountain View
Introduction to Data Science with H2O- Mountain ViewSri Ambati
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talkdtdannen
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Tony Frame
 

Semelhante a Dev Link2009 Multi Tenancy Beyond The Whiteboard Chris Hefley (20)

Services Stanford 2012
Services Stanford 2012Services Stanford 2012
Services Stanford 2012
 
Building Social Enterprise with Ruby and Salesforce
Building Social Enterprise with Ruby and SalesforceBuilding Social Enterprise with Ruby and Salesforce
Building Social Enterprise with Ruby and Salesforce
 
Elegant Rest Design Webinar
Elegant Rest Design WebinarElegant Rest Design Webinar
Elegant Rest Design Webinar
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web Development
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
HackMiami-Final
HackMiami-FinalHackMiami-Final
HackMiami-Final
 
External to DA, the OS X Way
External to DA, the OS X WayExternal to DA, the OS X Way
External to DA, the OS X Way
 
Symfony + GraphQL
Symfony + GraphQLSymfony + GraphQL
Symfony + GraphQL
 
Graphql + Symfony | Александр Демченко | CODEiD
Graphql + Symfony | Александр Демченко | CODEiDGraphql + Symfony | Александр Демченко | CODEiD
Graphql + Symfony | Александр Демченко | CODEiD
 
Tornadoweb
TornadowebTornadoweb
Tornadoweb
 
Basic of Big Data
Basic of Big Data Basic of Big Data
Basic of Big Data
 
Big data, just an introduction to Hadoop and Scripting Languages
Big data, just an introduction to Hadoop and Scripting LanguagesBig data, just an introduction to Hadoop and Scripting Languages
Big data, just an introduction to Hadoop and Scripting Languages
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat
 
Introduction to data science with H2O-Chicago
Introduction to data science with H2O-ChicagoIntroduction to data science with H2O-Chicago
Introduction to data science with H2O-Chicago
 
Introduction to Data Science with H2O- Mountain View
Introduction to Data Science with H2O- Mountain ViewIntroduction to Data Science with H2O- Mountain View
Introduction to Data Science with H2O- Mountain View
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talk
 
Java at lifeblob
Java at lifeblobJava at lifeblob
Java at lifeblob
 
New PHP Exploitation Techniques
New PHP Exploitation TechniquesNew PHP Exploitation Techniques
New PHP Exploitation Techniques
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01
 

Último

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 

Último (20)

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 

Dev Link2009 Multi Tenancy Beyond The Whiteboard Chris Hefley

Notas do Editor

  1. Ok, let’s get started. Hi, everyone, I’m Chris Hefley. The title of this talk is Multi-Tenancy, Beyond the whiteboard. First off, I’ll say that this is the kind of talk where a lot can go wrong. I’m going to try to show you some running code, stepping through it in the debugger and all, so if you see me do something stupid, speak up…d m on’t let me flounder. Feel free to ask questions at any time, but if you have one and want to hold till just the right moment, watch for those times when Visual Studio starts grinding away on something, when there would normally be an awkward silence, and go ahead and just holler out your question then. I’ll admit now that some of the examples I promised you, like Linq2Sql, are not in here. I can’t get the visual designer for Linq2Sql or the server explorer to show up in Visual Studio on this machine right now, so I didn’t get a chance to do that one. But the important stuff here is architectural, and whether you use Lin2Sql or NHibernate or just roll your own isn’t so important. And hopefully I can leave time for some lively discussion at the end.
  2. First off, what is Multi-Tenancy? In simplistic terms, it the architecture we use to offer software as a service, where a single instance of your application is used by multiple clients, each of whom has their own, usually private, virtual copy of the application just for them. When you sign up for a BaseCamp or SalesForce.com or Facebook account, you are becoming a tenant in someone’s multi-tenant application.
  3. The biggest architectural decision you are going to have to make when developing a multi-tenant application is how to partition the data for different tenants. We’re just going to skim over these and acknowledge that each has it’s place, without debating all the pros and cons and dealing with all the religious wars that ensue. The code and design patterns we are going to look at later, however, will help you to implement some of these data partitioning schemes, so we’ll just describe each briefly here and move on.Ok, so first off, there’s Database Per Tenant In some verticals, like Healthcare and Financials, this may be the only option you have for some applications. It’s great for security, but can get very difficult to maintain if you’re not very strict and very careful to keep everything in sync.In Schema per tenant, there’s one database, but a separate copy of each table for each tenant. In TenantID per Row, every row in every table has a TenantID column. Every database query from you application includes “Where TenantID = The CurrentTenantId”. One of the nice things about this approach is that it’s easy to change your mind and switch to a separate database, if you want to. It’s easy to extract the data for one client from the system, by just copying everything from all tables that has the same TentantIDIn Tenant as Aggregate Root, the “Tenant” or “Organization” or “Client” table is the parent of every other table in the model. So for a project management application, you might have an Organization, which has a one-to-many relationship to the Projects table and the Users table. The Projects table would have a one-to-many relationship to the ProjectItems table and the Milestones table, etc. Your application has to enforce the separation by always joining to the appropriate parent table when retrieving things from the database.
  4. Some other considerations that will come up:The Url. Does everyone log into the app at the same url? My personal favorite is the subdomain approach, which can even be expanded so that you have tenant.subtenant.app.comThis third choice is especially nice for social applications like twitter and facebook, where each tenant is actually part of a larger community, and shares information with other tenants and possibly the public.And finally, for some applications it makes sense to allow the client to supply their own domain name, which you redirect to their hosted instance of your app. In some cases like when opening a Yahoo! Store, buying a domain name and having it set up for you can even be part of the signup process for your mult-tenant application.As far as data access strategy, you have object-relational mappers like Nhibernate, EntityFramework, Linq2Sql, or you can write your own dynamic sql queries in your app, or use stored procedures.
  5. The first design pattern we’re going to look at is the Repository pattern. Basically, a repository is an object that sits between your domain model and you data access layer. It provides an object oriented abstraction over data access. While the methods on your data access objects are going to be the pretty typical “CRUD” methods, the methods on your repository will be more meaningful in terms of your application domain.You might have a Find method that takes a “Query” object – basically an object that looks something like the object you are searching for, in this case Person, and has the fields filled in that you are interested in. So, personQuery might have all it’s fields = null, but the username field has “chris” and maybe there’s an enum that allows to specify “begins with”, “contains” or “exact”.The repostory could deconstruct that patientQuery, call the Data Access method (RetrieveOne or RetrieveAll), and pass in a list of relevant parameters that get turned into a real database query.You might also have meaningful methods like ListUsersByProject that eventually get turned into the more mundane parameters and database query by the data access layer.Take a look at the code:IRepostory<T>IUserRepositoryUserRepository
  6. I proposed earlier that for most multi-tenant applications, the bulk of the application should be blissfully ignorant of the fact that it is a multi-tenant application. (again, the exception is a community application like Facebook, where interacting with the other tenant is desirable).I’m proposing now that the Repository should be that boundary in your application where, everything above the respository “Knows nothing” of Multi-Tenancy. This includes those application services that instantiate and call the methods on the repository – they should not be passing a TenantId into repository methods, they should just ask for the objects they want, and the repository should figure out that they mean….all the objects they want “for the current tenant”.So, if the application can’t tell the repository which Tenant it belongs to, then how does the repository get that information?
  7. The answer lies in our next pattern: Dependency Injection and Inversion of Control. When I look back over my career, I can identify moments in my growth process where I learned some new concept, or finally really, really understood some concept that had been vague before, but suddenly became clear. I can identify certain ones of those moments that were “game changing” – after which what I learned began to effect everything I did – and became part of almost every bit of code I wrote.This is one of those. Until you really grasp it, it looks a little intimidating to most people. At least, it did to me at first. But once I stopped just reading blog posts about how important some people thought it was, and rolled up my sleeves and decided to try it, I found that it is really, really simple. I mean, really simple.Now I’m not sure I can teach this design pattern effectively with four slides. But I’m going to dispense with all the formal definitions, and I’m not going to try to show you a complete understanding of how it works, but I’m going to show a very simple example of the most common way in which I use it, that hopefully will be an ah-hah moment for some of you.Here you have UserRepository class, and it depends on a DataAccess object to actually create queries and retrieve records from the database.In the first example, you have this dependency, so you just ensure that you “new up” an instance of the object you need.The second bit of code is an example of something called “contstructor injection” – that is, you “inject” the depended upon objects into your class via the constructor. No big deal, right? So, let’s think about the implications of doing it this way. Obviously, whoever creates the UserRepository will have to create an instance of the User DAO and pass it into the constructor for UserRepository when it gets created. So wait a minute, is that better than what we had before? Haven’t we increased our dependencies, not decreased them? Now, my UserAdminService class that uses the UserRepository to perform its work will have to know about the DAO? Well, that sucks.
  8. But wait, there’s more. What we just saw was dependency injection. Another pattern, which can be seen really as the second half of the same pattern, is called Inversion of Control. Now there are a lot of freely available Inversion Of Control implementations out there, and all of them have more features than this, but in order to make it simple, I’ve contrived the most basic example of an IOC Container (that’s inversion of control container) that you may ever see.
  9. I thought I was really cooking when I started using Dependency Injection, because it made it so much easier to isolate the components I wanted to test, by allowing me to provide mock objects for the dependencies I wasn’t trying to test.But at that point, the whole IOC container thing was just sort of “there” for me…I was basically breaking my application up into smaller pieces and removing the connections between them, and it was the IOC containers job to piece those all together for me when I was actually running my application, and not just running tests.But the real power of an IOC container is what we’re going to use it for today. I said before that we wanted our repositories to be the boundary in our application, so that the repository would know about the Tenant, but the rest of the application would not. We’re going to do that by “injecting” knowledge of the tenant into the repository, and depending on our IOC container to supply that knowledge to the repository when it is instantiated.