Download Patterns with Microsoft SharePoint

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Psychometrics wikipedia , lookup

Transcript
Robert Bogue
MS MVP, SharePoint (MOSS)
Thor Projects
ARC309
Agenda
Overview of patterns and practices
What are patterns and why use them?
Overview of patterns introduced in
SharePoint version 1
Refactor Model-View-Presenter
Why unit testing?
Why is unit testing SharePoint hard?
Deeper dive on mocking
Questions and answers
SharePoint Guidance – Version 1
Design, build, test, deploy and upgrade SharePoint intranet applications
http://www.microsoft.com/spg
Patterns
Factoring and packaging
Team-based development
App Lifecycle Management
Design tradeoffs
http://www.codeplex.com/spg
Upgrading applications
Unit testing
Designing for testability
Continuous integration
Build verification testing
What are Design Patterns?
A design pattern is a general reusable solution
to a commonly occurring problem in software
design. A design pattern is not a finished design
that can be transformed directly into code. It is
a description or template for how to solve a
problem that can be used in many different
situations.
- Wikipedia
Why Use Patterns?
Design patterns can speed up the development
process by providing tested, proven development
paradigms. Effective software design requires
considering issues that may not become visible until
later in the implementation. Reusing design patterns
helps to prevent subtle issues that can cause major
problems, and it also improves code readability for
coders and architects who are familiar with the
patterns.
- Wikipedia
What Do Patterns Cost?
In order to achieve flexibility, design patterns
usually introduce additional levels of
indirection, which in some cases may
complicate the resulting designs and hurt
application performance.
- Wikipedia
Patterns Help Frame What to Do…
Increase productivity
Common problems →
common solutions
Leverages experience
Lower long term costs
Easier to test
Increases flexibility
Easier to maintain
Easier to evolve
Patterns Applied to SharePoint in
Version 1 Guidance
View
Presenter
Model-View-Presenter
Model
Locates
ClassA
IServiceA serviceA =
ServiceLocator.Get<IServiceA>()
Locates
Service Locator
IServiceB serviceB =
ServiceLocator.Get<IServiceB>()
Custom
Business
Logic
Repository
Service
Locator
ServiceA
Repository
ServiceB
SharePoint
Lists
Deep Dive - Model View Presenter
Similar to Model View Controller
Separation of view from
presentation logic
Separation of role responsibility
View
Presenter
Model
Business entities
Services
Data Repositories
View
Markup
Logic for conditional formatting
Presenter
Logic for taking action on events
resulting from user gestures and
model changes
Model
Factoring Out View and Presenter
Service Locator Motivation
Loosely couple service provider and consumer
Provides a pluggable implementation
Improves test coverage
“Poor mans” dependency injection – reduce
complexity introduced
Tightly Coupled Service Dependencies
Uses
ClassA
ServiceA
ServiceA serviceA = new
ServiceA()
Uses
ServiceB serviceB = new
ServiceB()
ServiceB
Service Location
Locates
ClassA
Service
Locator
ServiceA
IServiceA serviceA =
ServiceLocator.Get<IServiceA>()
Locates
ServiceB
IServiceB serviceB =
ServiceLocator.Get<IServiceB>()
Repository Motivation
Improves test coverage
Better separation of data and business tiers
Reduces opportunity for erroneous or poor
practices with list access
Adding an Item to a List SharePoint API
//-- Direct List Data Access ----------------// Adds a new SPListItem directly to the list.
SPList list = web.Lists[Lists.Announcements];
SPListItem item = list.Items.Add();
item[Fields.Title] = "Direct List Data Access";
item[Fields.Body] =
"Item added using Direct List Data Access.";
web.AllowUnsafeUpdates = true;
item.Update();
web.AllowUnsafeUpdates = false;
id = item.ID;
Adding Via AnnouncementRepository
//-- AnnoucementRepostitory Data Access ----------// Adds a new Announcement using the AnnouncementRepository.
AnnouncementRepository announcementRepository =
new AnnouncementRepository();
Announcement announcement = new Announcement()
{
Title = "AnnouncementRepository Data Access",
Body = "Item added using AnnouncementRepository."
};
id = announcementRepository.Add(announcement, web);
What is Wrong with This Code?
SPList bigList = web1.Lists[“BigList”];
foreach(SPListItem item in bigList.Items)
{
if(item[“MyColumn”] == “Foo”)
{
Console.WriteLine(“Found One!”);
}
}
Working with SPList
SPList.Items gets a collection with ALL list items
Terrible for big lists
Lots of memory needed
Lots of SQL I/O
Lots of network
Lots of CPU
Instead use SPList.GetItems
Takes a CAML query
Now Using a Repository…
//BigList access code refactored using repository
BigListRepository bigListRepository =
new BigListRepository();
Ilist<BigListItem> bigListItems =
bigListRepository.GetByMyColumn(“Foo”);
if (bigListItems.Count >0)
Console.WriteLine(“Found One!”);
RI Architecture - Before
IIS
Workflow
Activities
Workflow
SharePoint
Accounting
ASPX Pages
Web Parts
HR
RI Architecture - After
ASPX Pages
Web Parts
IIS
Accounting
HR
Repositories
SharePoint
Presenters
Workflow
Controllers
Workflow
Activities
Workflow
Where Do Patterns and Practices use
Unit Testing?
Develop and build
Source
Control
Stand Alone
Stand Alone
Development
Stand Alone
Development
Environments
Development
Environments
Environments
Continuous
Integration
Server
Build and unit test on
check-in events
Development Owned
Automated
Build
Verification
Test Server
Validated
WSP
Automated build and build
verification test ran periodically
Test Owned
How Does Unit Testing Help?
Quickly validates code logic executing correctly
Rapidly iterate code/test
Rapid identification of breaking changes
Improved quality and frequency of check-in
Avoids the dreaded mondo check-in
Builds confidence to re-factor
Enables CI
What Unit Testing Doesn’t Do:
Ensure that code is functionally correct
Load or stress test the code (see integration tests)
Is This a Unit Test?
[TestMethod]
[ExpectedException(typeof(SPException), "The Enrollment Deadline Date can not be
before today's date.\r\n")]
public void AddingCourseWithInvalidEnrollmentDateCancelsWithError()
{
//Setup our mock so that our enrollment date is invalid
TrainingCourse course = new TrainingCourse
{
Title = "My Title",
Code = "12345678",
EnrollmentDate = DateTime.Today.AddDays(-1),
StartDate = DateTime.Today.AddDays(1),
EndDate = DateTime.Today.AddDays(2),
Cost = 100
};
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.AllWebs[webId])
{
TrainingCourseRepository repository = new TrainingCourseRepository();
repository.Add(course, web);
}
}
}
Background: Unit Testing (Agile Definition)
Tests business logic in
class/method being examined
No SharePoint logic
Dependencies isolated and
pass in
Breaking change affects only a
few unit tests
Background: Integration Testing (Agile Definition)
Evaluates integrated business logic
Tests real system behavior
Often complex setup/teardown logic
Typically no UI
Breaking change often affects
multiple tests
Why is it So Hard to Unit test in SharePoint?
What are Substitutes and How Do They Fit?
Test
Production Code
UnderlyingSubstitute
Dependencies (For
(Mock,
Example,
Stub,
SharePoint)
Wrapper)
Integration Test
Alternatives for Unit Testing
With SharePoint?
Wrapper/Façade
Surround all SharePoint APIs with classes that wrap
functionality
Wrapper redirects calls under test to a test implementation
(Mock or Stub)
Generally prohibitively costly to achieve
Typemock Isolator
Third party tool
Uses IL interception
SharePoint licensing model is reasonable cost
Wouldn’t it Be Nice if…
[TestMethod]
public void GetsContentFromListAndSetsInView()
{
//Arrange
SPWeb mockWeb = new SPWeb();
mockWeb.Lists.Add(“List Name”, “mock list”, customerListTemplate;
SPList mockList = mockWeb.Lists[“List Name”];
SPListItem mockListItem = mockList.Items.Add();
mockListItem[“First Name”] = “testfirstname”;
IMyView view = new MockMyView();
//Act
MyViewPresenter presenter = new MyViewPresenter(view);
presenter.GetContent();
//Assert
Assert.AreEqual(1, view.Content.Count);
Assert.AreEqual(“testfirstname”, view.Content[0].[“First Name”]);
}
Unfortunately, can’t construct SPWeb…
Bringing Patterns and Unit
Testing Together
Model-View-Presenter to test web forms
Increases unit test surface area for logic that is often in code behind
Mock views to test presenter in unit tests
Use repositories to encapsulate access to SPList instances
(Training Courses, Registrations…)
Mock repositories for unit tests
Use ServiceLocator to help swap mock services in place of
real ones
Use Typemock to mock calls to SharePoint API
Test logic that is previously not easily unit testable (like event receivers)
Resources
www.microsoft.com/teched
www.microsoft.com/learning
Sessions On-Demand & Community
Microsoft Certification & Training Resources
http://microsoft.com/technet
http://microsoft.com/msdn
Resources for IT Professionals
Resources for Developers
www.microsoft.com/learning
Microsoft Certification and Training Resources
Related Content
Patterns and practices SharePoint guidance
(http://www.microsoft.com/spg and
http://www.codeplex.com/spg)
SharePoint Best Practices Center
http://technet.microsoft.com/enus/office/sharepointserver/bb736746.aspx
SharePoint ALM Resource Center
http://msdn.microsoft.com/en-us/office/cc990283.aspx
Team Foundation Server Resource Center
http://msdn.microsoft.com/en-us/office/cc990283.aspx
Complete an
evaluation on
CommNet and
enter to win!
© 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should
not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS,
IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.