Tuesday, December 28, 2010

Creating an Automocking container for Moq using Unity

Auto mocking allows you to get object of the type you want to test without setting up mocks by hand. Using an auto mocker you can create the mock classes with dependencies and the container will automatically resolve the dependencies for you. The auto mocker will also keep track of all the mocks it creates, and allows you to retrieve them if you need to stub a specific behavior. In this post we'll se how to create an auto mocking container for Moq using Unity.
The container implementation mainly has 2 methods GetMock and Create.
The GetMock is used to get the Mock of the object so that you can setup expectations and behaviours and later use this for verification.
public Mock GetMock(params object[] constructorParameters) where T : class
{
    var _mockedObject = (IMocked)this.Create(constructorParameters);
    return _mockedObject.Mock;
}

The Mock method is responsible for creating the mock and resolving dependencies
public T Create(params object[] constructorParameters) where T : class
{
    if (!_container.IsRegistered())
    {
        var mockedType = new Mock(constructorParameters).Object;
        var resolvedType = _container.BuildUp(mockedType);
        Register(resolvedType);
    }
    return _container.Resolve();
}

Test methods
Customer customer = CreateMockCustomerWithOrder();
var orderRepository = _mockContainer.GetMock<IOrderRepository>()
        .Setup(o => o.GetByCustomer(customer)).Returns(customer.Orders);

_mockContainer.Register<IOrderRepository>(_mockContainer.Create<IOrderRepository>());
ICustomerRepository customerRepository = _mockContainer.Create<CustomerRepository>();

customerRepository.Add(customer)

The UnityMockContainer code used in this sample.
public class UnityMockContainer
{
    IUnityContainer _container;

    public UnityMockContainer()
    {
        _container = new UnityContainer();
    }

    public Mock GetMock(params object[] constructorParameters) where T : class
    {
        var _mockedObject = (IMocked)this.Create(constructorParameters);
        return _mockedObject.Mock;
    }

    public T Create(params object[] constructorParameters) where T : class
    {
        if (!_container.IsRegistered())
        {
            var mockedType = new Mock(constructorParameters).Object;
            var resolvedType = _container.BuildUp(mockedType);
            Register(resolvedType);
        }
        return _container.Resolve();
    }

    public T Create(System.Linq.Expressions.Expression<Funcbool>> expression) where T : class
    {
        if (!_container.IsRegistered())
        {
            var mockedType = Moq.Mock.Of(expression);
            var resolvedType = _container.BuildUp(mockedType);
            Register(resolvedType);
        }
        return _container.Resolve();
    }

    public void Register() where TTo : TFrom
    {
        _container.RegisterType();
    }

    public T Resolve()
    {
        return _container.Resolve();
    }

    public void Register(TFrom instance)
    {
        _container.RegisterInstance(instance);
    }
}

Thursday, December 23, 2010

Custom RadOutlookBar region adapter – Silverlight, Prism, MEF

The Prism Library provides default control adapters for enabling a control as a region. Extensions around regions may involve providing custom region adapters, custom regions, or replacing the region manager. If you are planning to use a custom Silverlight control or a third party control that does not work with the provided region adapters, you may need to create a custom adapter for the control. In this post I'll show how to use the RadOutlookBar control as a region manager and create a custom adapter for it in Prism. I have used MEF container instead of unity in this sample.
To create a custom region adapter you need to inherit the RegionAdapterBase class or create an implementation for IRegionAdapter. The sample used in this post inherits the RegionAdapterBase class
public class TelerikOutlookBarRegionAdapter : RegionAdapterBase<RadOutlookBar>
{
    public TelerikOutlookBarRegionAdapter(IRegionBehaviorFactory regionBehaviourFactory) : base(regionBehaviourFactory) { }

    protected override void Adapt(IRegion region, RadOutlookBar regionTarget)
    {
        _outlookBar = regionTarget;
        _outlookBar.Items.Clear();
        region.ActiveViews.CollectionChanged +=
        new System.Collections.Specialized.NotifyCollectionChangedEventHandler((x, y) =>
        {
            switch (y.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (RadOutlookBarItem outlookBarButton in y.NewItems)
                        _outlookBar.Items.Add(outlookBarButton);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (RadOutlookBarItem outlookBarButton in y.NewItems)
                        _outlookBar.Items.Remove(outlookBarButton);
                    break;
            }
        });
        region.ActiveViews.ToList().ForEach(x => _outlookBar.Items.Add(x as RadOutlookBarItem));
    }

    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }

    RadOutlookBar _outlookBar;
}

Next we need to register the region adapter in the Bootstrappers ConfigureRegionAdapterMappings method.

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    var regionAdapterMappings = base.ConfigureRegionAdapterMappings();
    var regionBehaviourFactory = Container.GetExportedValueIRegionBehaviorFactory>();
    regionAdapterMappings.RegisterMapping(typeof(Telerik.Windows.Controls.RadOutlookBar), new TelerikOutlookBarRegionAdapter(regionBehaviourFactory));
    return regionAdapterMappings;
}

Adding a new Tab from a module can be done like
[ModuleExport("BlogsPrajeesh.PrismSamples.Configuration", typeof(ConfiguraitonModule))]
public class ConfiguraitonModule : IModule
{
    [ImportingConstructor]
    public ConfiguraitonModule(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        CreateNavigationTabAndRegisterModule();
    }

    private void CreateNavigationTabAndRegisterModule()
    {
        RadOutlookBarItem configurationModuleTab = new RadOutlookBarItem();
        configurationModuleTab.Header = "Configuration";       
        configurationModuleTab.IsSelected = true;

        configurationModuleTab.Content = CreateModulePanel();
        _regionManager.Regions["NavigationRegion"].Add(configurationModuleTab);
    }

    StackPanel CreateModulePanel()
    {
        StackPanel configurationPanel = new StackPanel();
        configurationPanel.Orientation = Orientation.Vertical;
        configurationPanel.Height = 450;
        configurationPanel.Children.Add(CreateModuleLinkItems("User Profile", () => OnUserProfileClicked()));
 //Add more links
        return configurationPanel;
    }

    HyperlinkButton CreateModuleLinkItems(string content, Action command)
    {
        HyperlinkButton configurationLinkItem = new HyperlinkButton();
        configurationLinkItem.HorizontalAlignment = HorizontalAlignment.Left;
        configurationLinkItem.Margin = new Thickness(5D, 5D, 0D, 5D);
        configurationLinkItem.Content = content;
        configurationLinkItem.Click += new RoutedEventHandler((x, y) => command.Invoke());
        return configurationLinkItem;
    }
    //Other methods…

    IRegionManager _regionManager;
}


Output

Wednesday, December 22, 2010

Configuring an MEF Container for Silverlight Prism4 applications

Prism supports modular application development by allowing you create a collection of modules that contains related components or features including user interface and business logic that can be developed independently and later integrated into the application. This feature of Prism makes is easier for develop, test, deploy and extend your application.
The module loading process in Prism includes the following:
1.       Registering/discovering modules. The modules to be loaded at run-time for a particular application are defined in a Module catalog. The catalog contains information about the modules to be loaded, their location, and the order in which they are to be loaded.
2.       Loading modules. The assemblies that contain the modules are loaded into memory. This phase may require the module to be downloaded from the web or otherwise retrieved from some remote location or local directory.
3.       Initializing modules. The modules are then initialized. This means creating instances of the module class and calling the Initialize method on them via the IModule interface.
In this post I’ll show how to create a module catalog by registering modules in XAML and the load them using an MefBootstrapper implementation in Silverlight.
·         In you prism application’s shell project add a reference to Microsoft.Practices.Prism.MefExtensions
·         Now change your Bootstrapper implementation to inherit the MefBootstrapper class
·         Create a new .xaml page and name it ModuleCatalog.xaml. This is the file which is used to specify the modules to be loaded. You need to override the CreateModuleCatalog method to return the ModuleCatalog.xamluri.
·         Override the  ConfigureAggregateCatalog method and add the assembly of the Shell project to the AssemblyCatalog collection .
The final implementation looks like
public class Bootstrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return this.Container.GetExportedValue<Shell>();    

    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        Application.Current.RootVisual = (UIElement)this.Shell;
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        return Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("/BlogsPrajeesh.PrismSamples.Shell;component/ModuleCatalog.xaml", UriKind.Relative));

    }

    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
    }
}

·         Create a new Silverlight application project. This will serve as a module in your application. Add references of the following assemblies to the project
§  Microsoft.Practices.Prism.MefExtensions
§  Microsoft.Practices.Prism
·         Create a new class that inherits the IModule interface. This is the entry point for your module.
[ModuleExport("BlogsPrajeesh.PrismSamples.Configuration", typeof(ConfiguraitonModule))]
public class ConfiguraitonModule : IModule
{
    public ConfiguraitonModule()
    {

    }
    public void Initialize()
    {
        //Initialization code goes here
    }
}

·         Make sure that the Copy Local property for the Prism assemblies in the module is set to False.
·         Next we can add the module to the catalog file.
<Modularity:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                          xmlns:sys="clr-namespace:System;assembly=mscorlib"
                          xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
    <Modularity:ModuleInfo Ref="BlogsPrajeesh.PrismSamples.Configuration.xap" ModuleName="BlogsPrajeesh.PrismSamples.Configuration" ModuleType="BlogsPrajeesh.PrismSamples.Configuration.ConfiguraitonModule, BlogsPrajeesh.PrismSamples.Configuration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />   
Modularity:ModuleCatalog>



Friday, December 17, 2010

Enterprise Library Security Application block – Rule based authorization

Enterprise library security application block's Authorization provider can be used to create an effective solution for rule based security implementation in your application code. The security application block can be used to configure an Authorization provider and use this to map task based authorization to complex combination of roles. Later you can use these rules to verify permissions on the current user to perform an action.
In this post, I’ll show a simple implementation of a rule based authorization provider and its uses. The data model used in our sample looks like

I have created some SQL scripts to insert data into the relevant tables.  
INSERT INTO [dbo].[Role]([Id] ,[Name]) VALUES (NEWID() ,'SuperUser')
INSERT INTO [dbo].[Role]([Id] ,[Name]) VALUES (NEWID() ,'Guest')
INSERT INTO [dbo].[Role]([Id] ,[Name]) VALUES (NEWID() ,'NormalUser')
GO


INSERT INTO [dbo].[User]([Id] ,[FirstName] ,[LastName] ,[Email] ,[Password])
     VALUES (NEWID() ,'SuperUserFName' ,'SuperUserLName' , 'SuperUser@Company.com' , 'SuperUserPassword')
INSERT INTO [dbo].[User]([Id] ,[FirstName] ,[LastName] ,[Email] ,[Password])
     VALUES (NEWID() ,'GuestFName' ,'GuestLName' , 'Guest@Company.com' , 'GuestPassword')
INSERT INTO [dbo].[User]([Id] ,[FirstName] ,[LastName] ,[Email] ,[Password])
     VALUES (NEWID() ,'NormalUserFName' ,'NormalUserLName' , 'NormalUser@Company.com' , 'NormalUserPassword')
INSERT INTO [dbo].[User]([Id] ,[FirstName] ,[LastName] ,[Email] ,[Password])
     VALUES (NEWID() ,'ITDeptFName' ,'ITDeptLName' , 'ITDept@Company.com' , 'ITDeptPassword')
GO


DECLARE @SuperUserId uniqueidentifier
DECLARE @SuperRoleId uniqueidentifier
SELECT @SuperUserId = Id FROM [User] WHERE [FirstName] = 'SuperUserFName'
SELECT @SuperRoleId = Id FROM [Role] WHERE [Name] = 'SuperUser'

INSERT INTO [dbo].[UserRole]([UserId], [RoleId] ,[Id])
     VALUES(@SuperUserId ,@SuperRoleId ,NEWID())
GO
Next we’ll configure rules using the Enterprise Library security application block.
1.       Open the App.Config file in the Enterprise Library Configuration editor and select Add Security Sections from the Blocks menu.
2.       Add a new Authorization rule provider as shown in the image below.

3.       Give an appropriate name and add a new Authorization rule to the provider. In this sample I have used the name as MyBusinessRule
4.       We will create two rules (AddProfile and ApproveProfileChanges).

5.       For the AddProfile rule add the Rule Expression as R:SuperUser AND R:NormalUser
6.       For the ApproveProfile rule the rule expression is R:SuperUser
7.       Save and close your config file.
8.       The final output looks like
<configSections>
  <section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null" requirePermission="true" />
configSections>
<securityConfiguration defaultAuthorizationInstance="MyBusinessRule">
  <authorizationProviders>
    <add type="Microsoft.Practices.EnterpriseLibrary.Security.AuthorizationRuleProvider, Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null"
      name="MyBusinessRule">
      <rules>
        <add expression="R:SuperUser" name="Approve Profile Changes" />
        <add expression="R:SuperUser AND R:NormalUser" name="Add Profile" />
      rules>
    add>
  authorizationProviders>
securityConfiguration>
9.       In your business layer add references to the following assemblies
·         Microsoft.Practices.EnterpriseLibrary.Common.dll
·         Microsoft.Practices.EnterpriseLibrary.Security.dll
·         Microsoft.Practices.ServiceLocation.dll
10.   Create a class RuleAuthorizationManager and add the authorization logic for the user role for a configured rule.
public class RuleAuthorizationManager
{
    public static bool IsUserAuthorized(string ruleName)
    {
        var ruleProvider = EnterpriseLibraryContainer.Current.GetInstance<IAuthorizationProvider>();
        return ruleProvider.Authorize(Thread.CurrentPrincipal, ruleName);
    }
}
11.      In the service class you can use the IsUserAuthorized method to check for permissions.
public void AddRoleToUser(Guid userId, Role role)
{
    if(!RuleAuthorizationManager.IsUserAuthorized(RuleNames.AddProfile))
        throw new SecurityException("User not authorized to add profile");

    var repository = new Repository(new UserModelContainer());
    var user = repository.GetSingle<User>(u => u.Id == userId);

    //Code to add a role to user.
}
Unit tests
[TestMethod()]
[ExpectedException(typeof(SecurityException))]
public void ApproveProfileChanges_should_throw_security_exception_if_user_does_not_have_permission_to_add_profile()
{
    UserService target = new UserService();
    User user = new Repository(new UserModelContainer()).GetSingle<User>(u => u.FirstName == "GuestFName");
    IIdentity identity = new GenericIdentity("Guest@Company.com");
    string[] roles = new string[] { "Guest" };

    IPrincipal principal = new GenericPrincipal(identity, roles);
    Thread.CurrentPrincipal = principal;

    target.ApproveProfileChanges(user);
}