From 9301c930de550a2c30ad6d179994bfa8411891f7 Mon Sep 17 00:00:00 2001 From: jeremydmiller Date: Mon, 14 Sep 2015 21:36:19 -0500 Subject: [PATCH 01/55] Documentation Update --- architecture/index.html | 34 +++++++++-- best-practices/index.html | 34 +++++++++-- diagnostics/build-plans/index.html | 34 +++++++++-- diagnostics/environment-tests/index.html | 34 +++++++++-- diagnostics/index.html | 34 +++++++++-- .../using-the-container-model/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- diagnostics/whatdoihave/index.html | 34 +++++++++-- documentation/index.html | 56 ++++++++++--------- faq/index.html | 34 +++++++++-- features/index.html | 34 +++++++++-- get-structuremap/index.html | 34 +++++++++-- glossary/index.html | 34 +++++++++-- history/index.html | 34 +++++++++-- index.html | 27 ++++++++- integrations/index.html | 34 +++++++++-- interception-and-decorators/index.html | 35 ++++++++++-- interpreting-exceptions/index.html | 34 +++++++++-- .../configuring-lifecycles/index.html | 34 +++++++++-- object-lifecycle/custom-lifecycles/index.html | 34 +++++++++-- object-lifecycle/index.html | 34 +++++++++-- .../supported-lifecycles/index.html | 34 +++++++++-- quickstart/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- .../configuring-the-raw-model/index.html | 34 +++++++++-- registration/constructor-selection/index.html | 34 +++++++++-- registration/fallback-services/index.html | 34 +++++++++-- registration/index.html | 34 +++++++++-- registration/inline-dependencies/index.html | 34 +++++++++-- .../on-missing-family-policies/index.html | 34 +++++++++-- registration/registry-dsl/index.html | 34 +++++++++-- .../setter-injection-policies/index.html | 34 +++++++++-- release-notes/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- .../get-a-service-by-plugintype/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- resolving/index.html | 34 +++++++++-- .../passing-arguments-at-runtime/index.html | 34 +++++++++-- .../requesting-a-concrete-type/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- roadmap/index.html | 34 +++++++++-- software-design-concepts/index.html | 34 +++++++++-- the-container/auto-wiring/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- the-container/index.html | 34 +++++++++-- the-container/nested-containers/index.html | 34 +++++++++-- .../profiles-and-child-containers/index.html | 34 +++++++++-- .../structuremap-assumptions/index.html | 34 +++++++++-- .../working-with-enumerable-types/index.html | 34 +++++++++-- .../working-with-generic-types/index.html | 34 +++++++++-- .../index.html | 34 +++++++++-- 54 files changed, 1618 insertions(+), 234 deletions(-) diff --git a/architecture/index.html b/architecture/index.html index 2c93936..750a125 100644 --- a/architecture/index.html +++ b/architecture/index.html @@ -33,7 +33,7 @@ StructureMap @@ -125,6 +128,29 @@

Internals and Architecture

+ + diff --git a/best-practices/index.html b/best-practices/index.html index 3bd5137..e4fcaa1 100644 --- a/best-practices/index.html +++ b/best-practices/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Best Practices

+ + diff --git a/diagnostics/build-plans/index.html b/diagnostics/build-plans/index.html index 2bfa1cf..6abfcaf 100644 --- a/diagnostics/build-plans/index.html +++ b/diagnostics/build-plans/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Build Plans

+ + diff --git a/diagnostics/environment-tests/index.html b/diagnostics/environment-tests/index.html index 77fdc17..38beb39 100644 --- a/diagnostics/environment-tests/index.html +++ b/diagnostics/environment-tests/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Environment Tests

+ + diff --git a/diagnostics/index.html b/diagnostics/index.html index b3369e9..67ee902 100644 --- a/diagnostics/index.html +++ b/diagnostics/index.html @@ -33,7 +33,7 @@ StructureMap @@ -127,6 +130,29 @@

Diagnostics

+ + diff --git a/diagnostics/using-the-container-model/index.html b/diagnostics/using-the-container-model/index.html index 655c131..7904a19 100644 --- a/diagnostics/using-the-container-model/index.html +++ b/diagnostics/using-the-container-model/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Using the Container Model

+ + diff --git a/diagnostics/validating-container-configuration/index.html b/diagnostics/validating-container-configuration/index.html index d2e7057..4563510 100644 --- a/diagnostics/validating-container-configuration/index.html +++ b/diagnostics/validating-container-configuration/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Validating Container Configuration

+ + diff --git a/diagnostics/whatdoihave/index.html b/diagnostics/whatdoihave/index.html index 901352f..85985ad 100644 --- a/diagnostics/whatdoihave/index.html +++ b/diagnostics/whatdoihave/index.html @@ -33,7 +33,7 @@ StructureMap @@ -178,6 +181,29 @@

Filtering WhatDoIHave()

+ + diff --git a/documentation/index.html b/documentation/index.html index b404626..cd04860 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -33,7 +33,7 @@ StructureMap @@ -90,27 +93,7 @@

Documentation

The documentation may never be exhaustive, but here are the major sections so far:

- +
@@ -145,6 +128,29 @@

Documentation

+ + diff --git a/faq/index.html b/faq/index.html index b321277..a5f4b32 100644 --- a/faq/index.html +++ b/faq/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

FAQ

+ + diff --git a/features/index.html b/features/index.html index e4002fc..23a6e8a 100644 --- a/features/index.html +++ b/features/index.html @@ -33,7 +33,7 @@ StructureMap @@ -163,6 +166,29 @@

Things StructureMap does not have

+ + diff --git a/get-structuremap/index.html b/get-structuremap/index.html index d988ff8..95133b9 100644 --- a/get-structuremap/index.html +++ b/get-structuremap/index.html @@ -33,7 +33,7 @@ StructureMap @@ -159,6 +162,29 @@

Source

+ + diff --git a/glossary/index.html b/glossary/index.html index 999ebec..468ac7f 100644 --- a/glossary/index.html +++ b/glossary/index.html @@ -33,7 +33,7 @@ StructureMap @@ -313,6 +316,29 @@

Auto wiring

+ + diff --git a/history/index.html b/history/index.html index 1b233bf..3492fda 100644 --- a/history/index.html +++ b/history/index.html @@ -33,7 +33,7 @@ StructureMap @@ -135,6 +138,29 @@

History

+ + diff --git a/index.html b/index.html index 3d5cd57..5ce9c5a 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,11 @@ Join the chat at https://gitter.im/structuremap/structuremap - + @@ -83,7 +87,28 @@

Integrations

+ diff --git a/integrations/index.html b/integrations/index.html index 9413184..a80d5be 100644 --- a/integrations/index.html +++ b/integrations/index.html @@ -33,7 +33,7 @@ StructureMap @@ -136,6 +139,29 @@

Integrating StructureMap into Common .Net Frameworks

+ + diff --git a/interception-and-decorators/index.html b/interception-and-decorators/index.html index 8a99dcc..72d703b 100644 --- a/interception-and-decorators/index.html +++ b/interception-and-decorators/index.html @@ -33,7 +33,7 @@ StructureMap @@ -91,6 +94,7 @@

Interception and Decorators

+

Until official documentation is completed, you can analyze the user acceptance tests for help with this topic.

TODO(Write some content!)

@@ -126,6 +130,29 @@

Interception and Decorators

+ + diff --git a/interpreting-exceptions/index.html b/interpreting-exceptions/index.html index 1c98d46..da908c1 100644 --- a/interpreting-exceptions/index.html +++ b/interpreting-exceptions/index.html @@ -33,7 +33,7 @@ StructureMap
@@ -126,6 +129,29 @@

Interpreting Exceptions

+ + diff --git a/object-lifecycle/configuring-lifecycles/index.html b/object-lifecycle/configuring-lifecycles/index.html index 72d2cfa..93b18e5 100644 --- a/object-lifecycle/configuring-lifecycles/index.html +++ b/object-lifecycle/configuring-lifecycles/index.html @@ -33,7 +33,7 @@ StructureMap @@ -177,6 +180,29 @@

Configuring Lifecycles

+ + diff --git a/object-lifecycle/custom-lifecycles/index.html b/object-lifecycle/custom-lifecycles/index.html index c8931b8..2cbdd24 100644 --- a/object-lifecycle/custom-lifecycles/index.html +++ b/object-lifecycle/custom-lifecycles/index.html @@ -33,7 +33,7 @@ StructureMap @@ -169,6 +172,29 @@

Custom Lifecycles

+ + diff --git a/object-lifecycle/index.html b/object-lifecycle/index.html index da8b376..7ed486a 100644 --- a/object-lifecycle/index.html +++ b/object-lifecycle/index.html @@ -33,7 +33,7 @@ StructureMap @@ -197,6 +200,29 @@

Motivation for Container Managed Scope

+ + diff --git a/object-lifecycle/supported-lifecycles/index.html b/object-lifecycle/supported-lifecycles/index.html index ca13c52..bf14302 100644 --- a/object-lifecycle/supported-lifecycles/index.html +++ b/object-lifecycle/supported-lifecycles/index.html @@ -33,7 +33,7 @@ StructureMap @@ -471,6 +474,29 @@

Legacy ASP.Net Lifecycles

+ + diff --git a/quickstart/index.html b/quickstart/index.html index 5d8f22c..4a3e018 100644 --- a/quickstart/index.html +++ b/quickstart/index.html @@ -33,7 +33,7 @@ StructureMap @@ -219,6 +222,29 @@

Need Help?

+ + diff --git a/registration/auto-registration-and-conventions/index.html b/registration/auto-registration-and-conventions/index.html index 27184ec..6b0151e 100644 --- a/registration/auto-registration-and-conventions/index.html +++ b/registration/auto-registration-and-conventions/index.html @@ -33,7 +33,7 @@ StructureMap @@ -296,6 +299,29 @@

Custom Registration Conventions

+ + diff --git a/registration/changing-configuration-at-runtime/index.html b/registration/changing-configuration-at-runtime/index.html index abfb810..a3ce2d1 100644 --- a/registration/changing-configuration-at-runtime/index.html +++ b/registration/changing-configuration-at-runtime/index.html @@ -33,7 +33,7 @@ StructureMap @@ -159,6 +162,29 @@

Best Practices

+ + diff --git a/registration/configuring-the-raw-model/index.html b/registration/configuring-the-raw-model/index.html index e79005c..21988dc 100644 --- a/registration/configuring-the-raw-model/index.html +++ b/registration/configuring-the-raw-model/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Configuring the Raw Model

+ + diff --git a/registration/constructor-selection/index.html b/registration/constructor-selection/index.html index b874dd4..9d046c2 100644 --- a/registration/constructor-selection/index.html +++ b/registration/constructor-selection/index.html @@ -33,7 +33,7 @@ StructureMap @@ -325,6 +328,29 @@

Custom Constructor Selection Rule

+ + diff --git a/registration/fallback-services/index.html b/registration/fallback-services/index.html index f16b88a..300dc0b 100644 --- a/registration/fallback-services/index.html +++ b/registration/fallback-services/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Fallback Services

+ + diff --git a/registration/index.html b/registration/index.html index 41ca884..0d77e91 100644 --- a/registration/index.html +++ b/registration/index.html @@ -33,7 +33,7 @@ StructureMap @@ -245,6 +248,29 @@

Registration

+ + diff --git a/registration/inline-dependencies/index.html b/registration/inline-dependencies/index.html index 603042a..4f493c1 100644 --- a/registration/inline-dependencies/index.html +++ b/registration/inline-dependencies/index.html @@ -33,7 +33,7 @@ StructureMap @@ -491,6 +494,29 @@

Programmatic Configuration outside of the Registry DSL

+ + diff --git a/registration/on-missing-family-policies/index.html b/registration/on-missing-family-policies/index.html index c821361..9500172 100644 --- a/registration/on-missing-family-policies/index.html +++ b/registration/on-missing-family-policies/index.html @@ -33,7 +33,7 @@ StructureMap @@ -323,6 +326,29 @@

Using a Custom IFamilyPolicy" id="custom">

+ + diff --git a/registration/registry-dsl/index.html b/registration/registry-dsl/index.html index eb57c15..34a4173 100644 --- a/registration/registry-dsl/index.html +++ b/registration/registry-dsl/index.html @@ -33,7 +33,7 @@ StructureMap @@ -199,6 +202,29 @@

Named Instances

+ + diff --git a/registration/setter-injection-policies/index.html b/registration/setter-injection-policies/index.html index f695e38..ff217ba 100644 --- a/registration/setter-injection-policies/index.html +++ b/registration/setter-injection-policies/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Setter Injection Policies

+ + diff --git a/release-notes/index.html b/release-notes/index.html index 88d9ae8..fcaffbd 100644 --- a/release-notes/index.html +++ b/release-notes/index.html @@ -33,7 +33,7 @@ StructureMap @@ -196,6 +199,29 @@

Release Notes 3.0

+ + diff --git a/resolving/get-a-service-by-plugin-type-and-name/index.html b/resolving/get-a-service-by-plugin-type-and-name/index.html index d1e4fde..1b55027 100644 --- a/resolving/get-a-service-by-plugin-type-and-name/index.html +++ b/resolving/get-a-service-by-plugin-type-and-name/index.html @@ -33,7 +33,7 @@ StructureMap @@ -149,6 +152,29 @@

Get a Service by Plugin Type and Name

+ + diff --git a/resolving/get-a-service-by-plugintype/index.html b/resolving/get-a-service-by-plugintype/index.html index 603b929..b30970e 100644 --- a/resolving/get-a-service-by-plugintype/index.html +++ b/resolving/get-a-service-by-plugintype/index.html @@ -33,7 +33,7 @@ StructureMap @@ -142,6 +145,29 @@

Get a Service by PluginType

+ + diff --git a/resolving/get-all-services-by-plugin-type/index.html b/resolving/get-all-services-by-plugin-type/index.html index ffe6753..e351df1 100644 --- a/resolving/get-all-services-by-plugin-type/index.html +++ b/resolving/get-all-services-by-plugin-type/index.html @@ -33,7 +33,7 @@ StructureMap @@ -153,6 +156,29 @@

Get all Services by Plugin Type

+ + diff --git a/resolving/index.html b/resolving/index.html index e77cbff..0213a47 100644 --- a/resolving/index.html +++ b/resolving/index.html @@ -33,7 +33,7 @@ StructureMap @@ -127,6 +130,29 @@

Resolving Services

+ + diff --git a/resolving/passing-arguments-at-runtime/index.html b/resolving/passing-arguments-at-runtime/index.html index dabf469..689d7c9 100644 --- a/resolving/passing-arguments-at-runtime/index.html +++ b/resolving/passing-arguments-at-runtime/index.html @@ -33,7 +33,7 @@ StructureMap @@ -246,6 +249,29 @@

Using the ExplicitArguments object

+ + diff --git a/resolving/requesting-a-concrete-type/index.html b/resolving/requesting-a-concrete-type/index.html index 32d22dc..64d3058 100644 --- a/resolving/requesting-a-concrete-type/index.html +++ b/resolving/requesting-a-concrete-type/index.html @@ -33,7 +33,7 @@ StructureMap @@ -182,6 +185,29 @@

Auto Resolving Concrete Types

+ + diff --git a/resolving/try-geting-an-optional-service-by-plugin-type-and-name/index.html b/resolving/try-geting-an-optional-service-by-plugin-type-and-name/index.html index 56b0409..c65d3ea 100644 --- a/resolving/try-geting-an-optional-service-by-plugin-type-and-name/index.html +++ b/resolving/try-geting-an-optional-service-by-plugin-type-and-name/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Try Geting an Optional Service by Plugin Type and Name

+ + diff --git a/resolving/try-getting-an-optional-service-by-plugin-type/index.html b/resolving/try-getting-an-optional-service-by-plugin-type/index.html index c9691e9..de51239 100644 --- a/resolving/try-getting-an-optional-service-by-plugin-type/index.html +++ b/resolving/try-getting-an-optional-service-by-plugin-type/index.html @@ -33,7 +33,7 @@ StructureMap @@ -243,6 +246,29 @@

Optional Generic Types

+ + diff --git a/roadmap/index.html b/roadmap/index.html index ab7d72d..375f888 100644 --- a/roadmap/index.html +++ b/roadmap/index.html @@ -33,7 +33,7 @@ StructureMap @@ -137,6 +140,29 @@

Future Plans

+ + diff --git a/software-design-concepts/index.html b/software-design-concepts/index.html index 825eccf..715ffbe 100644 --- a/software-design-concepts/index.html +++ b/software-design-concepts/index.html @@ -33,7 +33,7 @@ StructureMap @@ -129,6 +132,29 @@

Service Locator

+ + diff --git a/the-container/auto-wiring/index.html b/the-container/auto-wiring/index.html index 1db6182..e9973c2 100644 --- a/the-container/auto-wiring/index.html +++ b/the-container/auto-wiring/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Auto Wiring

+ + diff --git a/the-container/forwarding-requests-for-a-type-to-another-type/index.html b/the-container/forwarding-requests-for-a-type-to-another-type/index.html index 9d9f6ac..0ab2516 100644 --- a/the-container/forwarding-requests-for-a-type-to-another-type/index.html +++ b/the-container/forwarding-requests-for-a-type-to-another-type/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Forwarding Requests for a Type to Another Type

+ + diff --git a/the-container/handling-missing-named-instances/index.html b/the-container/handling-missing-named-instances/index.html index cf11619..16f3b25 100644 --- a/the-container/handling-missing-named-instances/index.html +++ b/the-container/handling-missing-named-instances/index.html @@ -33,7 +33,7 @@ StructureMap @@ -298,6 +301,29 @@

Multi-Tenancy

+ + diff --git a/the-container/index.html b/the-container/index.html index 37e54bd..f2764d3 100644 --- a/the-container/index.html +++ b/the-container/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

The Container

+ + diff --git a/the-container/nested-containers/index.html b/the-container/nested-containers/index.html index de7f98f..7b7905c 100644 --- a/the-container/nested-containers/index.html +++ b/the-container/nested-containers/index.html @@ -33,7 +33,7 @@ StructureMap @@ -432,6 +435,29 @@

Disposing Services

+ + diff --git a/the-container/profiles-and-child-containers/index.html b/the-container/profiles-and-child-containers/index.html index 202869d..adcd681 100644 --- a/the-container/profiles-and-child-containers/index.html +++ b/the-container/profiles-and-child-containers/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Profiles and Child Containers

+ + diff --git a/the-container/structuremap-assumptions/index.html b/the-container/structuremap-assumptions/index.html index 524f015..d685e1a 100644 --- a/the-container/structuremap-assumptions/index.html +++ b/the-container/structuremap-assumptions/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

StructureMap Assumptions

+ + diff --git a/the-container/working-with-enumerable-types/index.html b/the-container/working-with-enumerable-types/index.html index 67148ef..a06bbd2 100644 --- a/the-container/working-with-enumerable-types/index.html +++ b/the-container/working-with-enumerable-types/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Working with Enumerable Types

+ + diff --git a/the-container/working-with-generic-types/index.html b/the-container/working-with-generic-types/index.html index a12ce2c..2473013 100644 --- a/the-container/working-with-generic-types/index.html +++ b/the-container/working-with-generic-types/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Working with Generic Types

+ + diff --git a/the-container/working-with-the-icontext-at-build-time/index.html b/the-container/working-with-the-icontext-at-build-time/index.html index b89f89a..5bb6a5d 100644 --- a/the-container/working-with-the-icontext-at-build-time/index.html +++ b/the-container/working-with-the-icontext-at-build-time/index.html @@ -33,7 +33,7 @@ StructureMap @@ -126,6 +129,29 @@

Working with the IContext at Build Time

+ + From a877cacabec06461274fc3bbf87cb3534802dac2 Mon Sep 17 00:00:00 2001 From: jeremydmiller Date: Thu, 1 Oct 2015 10:02:58 -0500 Subject: [PATCH 02/55] Documentation Update --- diagnostics/build-plans/index.html | 40 ++- diagnostics/environment-tests/index.html | 24 +- diagnostics/index.html | 4 +- diagnostics/type-scanning/index.html | 235 +++++++++++++++ .../using-the-container-model/index.html | 121 +++++++- .../index.html | 29 +- documentation/index.html | 2 +- .../index.html | 16 +- .../index.html | 6 +- registration/configured-instance/index.html | 156 ++++++++++ .../configuring-the-raw-model/index.html | 6 +- registration/fallback-services/index.html | 6 +- registration/index.html | 6 +- .../on-missing-family-policies/index.html | 6 +- registration/registry-dsl/index.html | 4 +- setter-injection/index.html | 274 ++++++++++++++++++ software-design-concepts/index.html | 44 ++- 17 files changed, 940 insertions(+), 39 deletions(-) create mode 100644 diagnostics/type-scanning/index.html create mode 100644 registration/configured-instance/index.html create mode 100644 setter-injection/index.html diff --git a/diagnostics/build-plans/index.html b/diagnostics/build-plans/index.html index 6abfcaf..9ae64cb 100644 --- a/diagnostics/build-plans/index.html +++ b/diagnostics/build-plans/index.html @@ -94,7 +94,45 @@

Build Plans

-

TODO(Write some content!)

+

StructureMap 3.0 introduced the concept of the "Build Plan." The build plan is a textual representation of exactly how StructureMap will build a given Instance, including:

+
    +
  1. What constructor function, if any, StructureMap is going to use for a concrete type
  2. +
  3. How it is resolving the constructor dependencies in a recursive fashion
  4. +
  5. Which setter properties for a concrete type receive dependencies and how those setter dependencies are built
  6. +
  7. The lifecycle used for the Instance
  8. +
  9. All interceptors applied to the Instance
  10. +
  11. Explicitly configured inline dependencies
  12. +
  13. Description of any Lambda or Func<T> that is used to construct the Instance object
  14. +
+

To retrieve the build plan for a configured Instance, use the queryable Container.Model to find the configured Instance and call DescribeBuildPlan(int maxDepth) to get the textual report as shown in this sample below:

+

+            var container = Container.For<VisualizationRegistry>();
+
+            var description = container.Model.For<IDevice>().Default
+                .DescribeBuildPlan(); 
+
+            Debug.WriteLine(description);
+
+

The result of the code above is this textual representation of how StructureMap will build and/or resolve the default of the IDevice plugin type:

+
+PluginType: StructureMap.Testing.Diagnostics.IDevice
+Lifecycle: Transient
+Decorator --> FuncInterceptor of StructureMap.Testing.Diagnostics.IDevice: new DeviceDecorator(IDevice)
+Decorator --> Decorator of type StructureMap.Testing.Diagnostics.CrazyDecorator
+    new CrazyDecorator(IDevice, IEngine, IFoo)
+      ┣ IDevice = The inner IDevice
+      ┃ ┗ new DefaultDevice()
+      ┣ IEngine = **Default**
+      ┗ IFoo = **Default**
+
+

For another example, you can retrieve the build plan for a named instance of a certain build plan with this code:

+

+            var description = theContainer.Model.For<IDevice>()
+                .Find("A")
+                .DescribeBuildPlan();
+
+

See Using the Container Model for more information on using Container.Model.

+

You can find many more examples of finding the build plan description from Container.Model from the unit tests in the StructureMap codebase.

diff --git a/diagnostics/environment-tests/index.html b/diagnostics/environment-tests/index.html index 38beb39..5e161cd 100644 --- a/diagnostics/environment-tests/index.html +++ b/diagnostics/environment-tests/index.html @@ -94,7 +94,29 @@

Environment Tests

-

TODO(Write some content!)

+

Years ago I worked with a legacy system that was particularly fragile in its deployment. While my team at the time and I made some serious improvements in the reliability of the automated deployment, the best thing we did was to add a set of environment tests to the deployment that verified that basic elements of the system were working like:

+
    +
  • Could our code access the configured database?
  • +
  • Was a certain COM object registered on the server? (I hated COM then and the years haven't changed my mind)
  • +
  • Could we connect via remoting to another deployed application?
  • +
+

The deployments still frequently failed, but we were able to spot and diagnose the underlying problems much faster with our new environment tests than we could before by trying to run and debug the not-quite-valid application.

+

One of the mechanisms we used for these environment tests was StructureMap's ability to mark methods on configured types as environment tests with the [ValidationMethod] attribute as shown below:

+

+        public class Database : IDatabase
+        {
+            [ValidationMethod]
+            public void TryToConnect()
+            {
+                // try to open a connection to the configured
+                // database connection string
+
+                // throw an exception if the database cannot
+                // be reached
+            }
+        }
+
+

Used in conjunction with StructureMap's ability to validate a container, you can use this technique to quickly support environment tests embedded into your system code.

diff --git a/diagnostics/index.html b/diagnostics/index.html index 67ee902..c5cff8a 100644 --- a/diagnostics/index.html +++ b/diagnostics/index.html @@ -94,8 +94,8 @@

Diagnostics

Improving StructureMap's ability to diagnose and explain both configuration and runtime problems was a very big goal -for the latest major release (3.0).

- +for the big 3.0 release and improved with additional type scanning diagnostics for 4.0.

+
diff --git a/diagnostics/type-scanning/index.html b/diagnostics/type-scanning/index.html new file mode 100644 index 0000000..66d1a2a --- /dev/null +++ b/diagnostics/type-scanning/index.html @@ -0,0 +1,235 @@ + + + + + + + + StructureMap - Type Scanning Diagnostics + + + + + + + + + + + + + + + + + + + +Fork me on GitHub + + + +
+ +
+ + +
+
+ + +
+

StructureMap 3.1.6

+
+ + + +

Next

Internals and Architecture

+

Previous

Using the Container Model

+ + +
+ + +
+

Type Scanning Diagnostics

+ +
+ +
+ + +

Type scanning and conventional auto-registration is a very powerful feature in StructureMap, but it has been frequently troublesome to users when things go wrong. To try to alleviate problems, StructureMap 4.0 introduces some new functionality for detecting and diagnosing problems with type scanning, mostly related to Assembly's being missing.

+

Assert for Assembly Loading Failures

+

At its root, most type scanning and auto-registration schemes in .Net frameworks rely on the Assembly.GetExportedTypes() method. Unfortunately, that method can be brittle and fail whenever any dependency of that Assembly cannot be loaded into the current process, even if your application has no need for that dependency. In StructureMap 3.* and before, that loading exception was essentially swallowed and lost. In StructureMap 4 and above, you can use this method to assert the presence of any assembly load exceptions during type scanning:

+

+            TypeRepository.AssertNoTypeScanningFailures();
+
+

The method above will throw an exception listing all the Assembly's that failed during the call to GetExportedTypes() only if there were any failures. Use this method during your application bootstrapping if you want it to fail fast with any type scanning problems.

+

What did StructureMap scan?

+

Confusion of type scanning has been a constant problem with StructureMap usage over the years -- especially if users are trying to dynamically load assemblies from the file system for extensibility. In order to see into what StructureMap has done with type scanning, 4.0 introduces the Container.WhatDidIScan() method.

+

Let's say that you have a Container that is set up with at least two different scanning operations like this sample from the StructureMap unit tests:

+

+            var container = new Container(_ =>
+            {
+                _.Scan(x =>
+                {
+                    x.TheCallingAssembly();
+
+                    x.WithDefaultConventions();
+                    x.RegisterConcreteTypesAgainstTheFirstInterface();
+                    x.SingleImplementationsOfInterface();
+                });
+
+                _.Scan(x =>
+                {
+                    // Give your scanning operation a descriptive name
+                    // to help the diagnostics to be more useful
+                    x.Description = "Second Scanner";
+
+                    x.AssembliesFromApplicationBaseDirectory(assem => assem.FullName.Contains("Widget"));
+                    x.ConnectImplementationsToTypesClosing(typeof(IService<>));
+                    x.AddAllTypesOf<IWidget>();
+                });
+            });
+
+            Debug.WriteLine(container.WhatDidIScan());
+
+

The resulting textual report is shown below:

+

Sorry for the formatting and color of the text, but the markdown engine does not like the textual report

+

+/*
+All Scanners
+================================================================
+Scanner #1
+Assemblies
+----------
+* StructureMap.Testing, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+
+Conventions
+--------
+* Default I[Name]/[Name] registration convention
+* Register all concrete types against the first interface (if any) that they implement
+* Register any single implementation of any interface against that interface
+
+
+Second Scanner
+Assemblies
+----------
+* StructureMap.Testing.GenericWidgets, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+* StructureMap.Testing.Widget, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+* StructureMap.Testing.Widget2, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+* StructureMap.Testing.Widget3, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+* StructureMap.Testing.Widget4, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+* StructureMap.Testing.Widget5, Version=4.0.0.51243, Culture=neutral, PublicKeyToken=null
+
+Conventions
+--------
+* Connect all implementations of open generic type IService<T>
+* Find and register all types implementing StructureMap.Testing.Widget.IWidget
+
+*/
+
+

The textual report will show:

+
    +
  1. All the scanning operations (calls to Registry.Scan()) with a descriptive name, either one supplied by you or the Registry type and an order number.
  2. +
  3. All the assemblies that were part of the scanning operation including the assembly name, version, and a warning if Assembly.GetExportedTypes() failed on that assembly.
  4. +
  5. All the configured scanning conventions inside of the scanning operation
  6. +
+

WhatDidIScan() does not at this time show any type filters or exclusions that may be part of the assembly scanner.

+

See also: Auto-Registration and Conventions

+ + +
+ +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + diff --git a/diagnostics/using-the-container-model/index.html b/diagnostics/using-the-container-model/index.html index 7904a19..5f01e1f 100644 --- a/diagnostics/using-the-container-model/index.html +++ b/diagnostics/using-the-container-model/index.html @@ -47,7 +47,7 @@ Join the chat at https://gitter.im/structuremap/structuremap
  • Previous
  • -
  • Next
  • +
  • Next
  • + @@ -182,7 +180,7 @@

    Things StructureMap does not have

    -}); +}); diff --git a/generics/index.html b/generics/index.html index f267fe4..a1a7912 100644 --- a/generics/index.html +++ b/generics/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Generic Types - - - - - - - - - + StructureMap - Generic Types + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Interception and Decorators

    -

    Previous

    Object Lifecycles

    - - -
    - - -
    -

    Generic Types Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Generic Types Edit on GitHub

    + +
    + +
    +

    StructureMap comes with some power abilities to exploit open generic types in .Net for extensibility and flexible handling within your system.

    Example 1: Visualizing an Activity Log

    @@ -126,13 +124,13 @@

    Example 1: Visualizing an Activity Log

    
                 var logs = new object[]
                 {
    -                new IssueCreated(), 
    -                new TaskAssigned(), 
    -                new Comment(), 
    +                new IssueCreated(),
    +                new TaskAssigned(),
    +                new Comment(),
                     new IssueResolved()
                 };
     
    -            // SAMPLE: using-visualizer-knowning-the-type   
    +            // SAMPLE: using-visualizer-knowning-the-type
                 // Just setting up a Container and ILogVisualizer
                 var container = Container.For<VisualizationRegistry>();
                 var visualizer = container.GetInstance<ILogVisualizer>();
    @@ -167,28 +165,25 @@ 

    Example 1: Visualizing an Activity Log

    Registering Open Generic Types

    Let's say to begin with all we want to do is to always use the DefaultVisualizer for each log type. We can do that with code like this below:

    
    -        [Test]
    +        [Fact]
             public void register_open_generic_type()
             {
                 var container = new Container(_ =>
                 {
    -                _.For(typeof (IVisualizer<>)).Use(typeof (DefaultVisualizer<>));
    +                _.For(typeof(IVisualizer<>)).Use(typeof(DefaultVisualizer<>));
                 });
     
    -            
    -            Debug.WriteLine(container.WhatDoIHave(@namespace:"StructureMap.Testing.Acceptance.Visualization"));
    -            
    +            Debug.WriteLine(container.WhatDoIHave(@namespace: "StructureMap.Testing.Acceptance.Visualization"));
     
                 container.GetInstance<IVisualizer<IssueCreated>>()
                     .ShouldBeOfType<DefaultVisualizer<IssueCreated>>();
     
                 Debug.WriteLine(container.WhatDoIHave(@namespace: "StructureMap.Testing.Acceptance.Visualization"));
    -            
    -
     
                 container.GetInstance<IVisualizer<IssueResolved>>()
                     .ShouldBeOfType<DefaultVisualizer<IssueResolved>>();
             }
    +
     

    With the configuration above, there are no specific registrations for IVisualizer<IssueCreated>. At the first request for that interface, StructureMap will run through its "missing family policies", one of which is @@ -219,7 +214,7 @@

    Generic Registrations and Default Fallbacks

    special HTML rendering while others can happily be rendered with the default visualization strategy. This behavior is demonstrated by the following code sample:

    
    -        [Test]
    +        [Fact]
             public void generic_defaults()
             {
                 var container = new Container(_ =>
    @@ -231,7 +226,6 @@ 

    Generic Registrations and Default Fallbacks

    _.For<IVisualizer<IssueCreated>>().Use<IssueCreatedVisualizer>(); }); - // We have a specific visualizer for IssueCreated container.GetInstance<IVisualizer<IssueCreated>>() .ShouldBeOfType<IssueCreatedVisualizer>(); @@ -241,6 +235,7 @@

    Generic Registrations and Default Fallbacks

    container.GetInstance<IVisualizer<TaskAssigned>>() .ShouldBeOfType<DefaultVisualizer<TaskAssigned>>(); } +

    Connecting Generic Implementations with Type Scanning

    StructureMap has an admittedly non-obvious way to handle this situation by creating a new subclass of Instance that will "know" how to create the real Instance for a closed type of IRepository<,>.

    @@ -464,6 +461,7 @@

    Example #2: Generic Instance Builder

    } } } +

    As you've probably surmised, the custom RepositoryInstance above is itself an open generic type and cannot be used directly until it has been closed. You could use this class directly if you have a very few document types like this:

    
    @@ -489,7 +487,7 @@ 

    Example #2: Generic Instance Builder

    // StructureMap will cache the object built out of this, // so the expensive Reflection hit only happens // once - var instanceType = typeof (RepositoryInstance<,>).MakeGenericType(types); + var instanceType = typeof(RepositoryInstance<,>).MakeGenericType(types); return Activator.CreateInstance(instanceType).As<Instance>(); } @@ -506,26 +504,28 @@

    Example #2: Generic Instance Builder

    public override Type ReturnedType { - get { return typeof (Repository<,>); } + get { return typeof(Repository<,>); } } } +

    The key part of the class above is the CloseType(Type[] types) method. At that point, we can determine the right type of RepositoryInstance<,> to build the requested type of IRepository<,>, then use some reflection to create and return that custom Instance.

    Here's a unit test that exercises and demonstrates this functionality from end to end:

    
    -        [Test]
    +        [Fact]
             public void show_the_workaround_for_generic_builders()
             {
                 var container = new Container(_ =>
                 {
    -                _.For(typeof (IRepository<,>)).Use(new RepositoryInstanceFactory());
    +                _.For(typeof(IRepository<,>)).Use(new RepositoryInstanceFactory());
                 });
     
                 container.GetInstance<IRepository<string, int>>()
                     .ShouldBeOfType<Repository<string, int>>();
     
    -            Debug.WriteLine(container.WhatDoIHave(assembly:Assembly.GetExecutingAssembly()));
    +            Debug.WriteLine(container.WhatDoIHave(assembly: GetType().GetAssembly()));
             }
    +
     

    After requesting IRepository<string, int> for the first time, the container configuration from Container.WhatDoIHave() is:

    @@ -548,12 +548,15 @@ 

    Example 3: Interception Policy against Generic Types

    { // Sending messages void SendMessage<T>(T message); + void SendMessage<T>() where T : new(); // Explicit registration void AddListener(object listener); + void RemoveListener(object listener); } +

    To register a listener for a particular type of event notification, you would implement an interface called IListener<T> shown below and directly add that object to the IEventAggregator:

    @@ -562,6 +565,7 @@

    Example 3: Interception Policy against Generic Types

    { void Handle(T message); } +

    In the application I'm describing, all of the listener objects were presenters or screen controls that were created by StructureMap, so it was convenient to allow StructureMap to register newly created objects with the IEventAggregator in an activation interceptor.

    What we want to do though is have an interception policy that only applies to any concrete type that implements some interface that @@ -576,7 +580,7 @@

    Example 3: Interception Policy against Generic Types

    public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance) { - if (instance.ReturnedType.FindInterfacesThatClose(typeof (IListener<>)).Any()) + if (instance.ReturnedType.FindInterfacesThatClose(typeof(IListener<>)).Any()) { Expression<Action<IContext, object>> register = (c, o) => c.GetInstance<IEventAggregator>().AddListener(o); @@ -584,10 +588,11 @@

    Example 3: Interception Policy against Generic Types

    } } } +

    To see our new interception policy in action, see this unit test from GitHub:

    
    -        [Test]
    +        [Fact]
             public void use_the_event_listener_registration()
             {
                 var container = new Container(x =>
    @@ -605,28 +610,29 @@ 

    Example 3: Interception Policy against Generic Types

    listener.Messages.Single().ShouldBeTheSameAs(message); } +
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -660,7 +666,7 @@

    Example 3: Interception Policy against Generic Types

    -}); +}); diff --git a/get-structuremap/index.html b/get-structuremap/index.html index d7366c2..5e1cb1e 100644 --- a/get-structuremap/index.html +++ b/get-structuremap/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Get StructureMap - - - - - - - - - + StructureMap - Get StructureMap + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Features

    -

    Previous

    Glossary

    - - -
    - - -
    -

    Get StructureMap Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Get StructureMap Edit on GitHub

    + +
    + +
    +

    Current Release

    The current version of StructureMap will always be available on Nuget. See the Release Notes for more information.

    @@ -110,25 +108,25 @@

    Source

    The StructureMap build tooling has recently changed. See the GitHub README for more information on how to build and work with the StructureMap codebase.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -162,7 +160,7 @@

    Source

    -}); +}); diff --git a/glossary/index.html b/glossary/index.html index 87588b4..aa209b7 100644 --- a/glossary/index.html +++ b/glossary/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Glossary - - - - - - - - - + StructureMap - Glossary + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Get StructureMap

    -

    Previous

    A Gentle Quickstart

    - - -
    - - -
    -

    Glossary Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Glossary Edit on GitHub

    + +
    + +
    +

    There are some terms that reoccur throughout the documentation and show up in the StructureMap API. Understanding these terms and how they relate to StructureMap isn't a prerequisite to using StructureMap, but it helps.

    Container

    Tools like StructureMap are generally known as Inversion of Control (IoC) Containers or Dependency Injection (DI) Containers. In the Java world they are also known as Lightweight Containers to differentiate them from the older EJB Containers.

    @@ -262,7 +260,7 @@

    Auto wiring

    public class UsingCrossover { - [Test] + [Fact] public void showing_auto_wiring() { var container = new Container(x => @@ -271,8 +269,8 @@

    Auto wiring

    x.For<Avenger>().Use<IronMan>(); }); - // Notice that at no point did we define how to - // build CrossoverEvent. + // Notice that at no point did we define how to + // build CrossoverEvent. var @event = container.GetInstance<CrossoverEvent>(); @event.Avenger.ShouldBeOfType<IronMan>(); @event.Xman.ShouldBeOfType<Cyclops>(); @@ -282,25 +280,25 @@

    Auto wiring

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -334,7 +332,7 @@

    Auto wiring

    -}); +}); diff --git a/history/index.html b/history/index.html index 2a53d7b..3971160 100644 --- a/history/index.html +++ b/history/index.html @@ -1,96 +1,94 @@ - + - StructureMap - History - - - - - - - - - + StructureMap - History + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Release Notes

    -

    Previous

    Best Practices

    - - -
    - - -
    -

    History Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    History Edit on GitHub

    + +
    + +
    +

    StructureMap was originally conceived in 2002 as the world's greatest object/relational mapping tool (and frankly a way for me to prove to prospective employers that I could actually code so I could move on from my non-coding architect position at that time). @@ -104,25 +102,25 @@

    History Jeremy Miller's updated retrospective talk at CodeMash 2015.

    -

    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -156,7 +154,7 @@

    History - + - StructureMap - Custom Instance Types - - - - - - - - - + StructureMap - Custom Instance Types + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Integrating StructureMap into Common .Net Frameworks

    -

    Previous

    Release Notes

    - - -
    - - -
    -

    Custom Instance Types Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Custom Instance Types Edit on GitHub

    + +
    + +
    +

    Most users will never need to implement a custom Instance type, but it does come up here and there. The easiest way is probably to subclass LambdaInstance as shown below:

    
    @@ -121,25 +119,25 @@ 

    Missing Name Instance Template

    Custom Instance types can override this method to provide a brand new Instance for a name. This functionality may be useful for multi-tenancy situations.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -173,7 +171,7 @@

    Missing Name Instance Template

    -}); +}); diff --git a/integrations/index.html b/integrations/index.html index 30e4828..a31fb45 100644 --- a/integrations/index.html +++ b/integrations/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Integrating StructureMap into Common .Net Frameworks - - - - - - - - - + StructureMap - Integrating StructureMap into Common .Net Frameworks + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - - -

    Previous

    Custom Instance Types

    - - -
    - - -
    -

    Integrating StructureMap into Common .Net Frameworks Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Integrating StructureMap into Common .Net Frameworks Edit on GitHub

    + +
    + +
    +

    Want to see more integrations or samples of how to integrate StructureMap with various .Net development tools? Let us know in Gitter or Github, or better yet, we take pull requests for documentation.

    ASP.Net MVC 5

    The StructureMap team recommends the StructureMap.MVC5 nuget for integrating @@ -118,25 +116,25 @@

    AutoMapper

    See My AutoMapper setup for StructureMap from Martijn Burgers.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -170,7 +168,7 @@

    AutoMapper

    -}); +}); diff --git a/interception-and-decorators/index.html b/interception-and-decorators/index.html index f4dce2a..308a4c0 100644 --- a/interception-and-decorators/index.html +++ b/interception-and-decorators/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Interception and Decorators - - - - - - - - - + StructureMap - Interception and Decorators + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Interpreting Exceptions

    -

    Previous

    Generic Types

    - - -
    - - -
    -

    Interception and Decorators Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Interception and Decorators Edit on GitHub

    + +
    + +
    +

    All of the samples from this topic are part of the user acceptance tests in the main codebase. There is also another example of using an interception policy with open generic types at the bottom of Generic Types

    @@ -149,10 +147,11 @@

    Decorators

    get { return _inner; } } } +

    Now, to see the decorator mechanism in action:

    
    -        [Test]
    +        [Fact]
             public void decorator_example()
             {
                 var container = new Container(_ =>
    @@ -168,6 +167,7 @@ 

    Decorators

    .ShouldBeOfType<WidgetHolder>() .Inner.ShouldBeOfType<AWidget>(); } +

    In effect, doing a decorator this way has the same effect (and build plan) as:

    
    @@ -226,18 +226,19 @@ 

    Interception Policies

    public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance) { - if (pluginType == typeof (IWidget)) + if (pluginType == typeof(IWidget)) { // DecoratorInterceptor is the simple case of wrapping one type with another // concrete type that takes the first as a dependency - yield return new DecoratorInterceptor(typeof (IWidget), typeof (WidgetHolder)); + yield return new DecoratorInterceptor(typeof(IWidget), typeof(WidgetHolder)); } } } +

    To use this custom interception policy, use the Policies.Interceptor() methods like this example:

    
    -        [Test]
    +        [Fact]
             public void use_a_custom_interception_policy()
             {
                 var container = new Container(x =>
    @@ -251,6 +252,7 @@ 

    Interception Policies

    .ShouldBeOfType<WidgetHolder>() .Inner.ShouldBeOfType<AWidget>(); } +

    As a helper for creating your own interception policies, you can also use the InterceptorPolicy<T> base class to conventionally apply some sort of IInterceptor to any number of Instance's:

    @@ -259,7 +261,7 @@

    Interception Policies

    Here's an example of InterceptorPolicy<T> in usage from the acceptance tests:

    
    -        [Test]
    +        [Fact]
             public void apply_policy_selectively_with_a_func()
             {
                 var activator1 = new ActivatorInterceptor<ITarget>(x => x.Activate());
    @@ -301,6 +303,7 @@ 

    Interception Policies

    throw new NotImplementedException(); } } +

    Some quick things to note:

      @@ -321,18 +324,20 @@

      Apply Activation Interception by Type

      Activated = true; } } +

      An implementation of Activateable from StructureMap's unit tests is shown below:

      
           public class AWidget : Activateable, IWidget
           {
           }
      +
       

      If you decide that you'd like StructureMap to call the Activate() method on any object it creates as part of its object creation and resolution process, we can register an interception policy in a Registry like this:

      
      -        [Test]
      +        [Fact]
               public void activate_by_action()
               {
                   var container = new Container(x =>
      @@ -346,13 +351,14 @@ 

      Apply Activation Interception by Type

      .ShouldBeOfType<AWidget>() .Activated.ShouldBeTrue(); } +

      There are several overloads of OnCreationForAll() covering cases with and without IContext

      Apply Decoration across a Plugin Type

      As shown above, you can use the Registry.For<T>().DecorateAllWith<TDecorator>() to apply decorators to all Instance's registered to a Plugin Type:

      
      -        [Test]
      +        [Fact]
               public void decorate_with_type()
               {
                   var container = new Container(x =>
      @@ -366,6 +372,7 @@ 

      Apply Decoration across a Plugin Type

      .Inner .ShouldBeOfType<AWidget>(); } +

      There are also several other overloads of DecorateAllWith() for user supplied expressions, filters, and descriptions. See the acceptance tests for interception in the StructureMap codebase for many more sample usages.

      @@ -378,7 +385,6 @@

      Add Interception to a Single Instance

      { r.For<ContextRecorder>().Use(recorder); - r.For<IService>().AddInstances(x => { x.Type<ColorService>() @@ -419,30 +425,30 @@

      Add Interception to a Single Instance

      .Ctor<string>("color").Is("Orange"); x.Object(new ColorService("Yellow")).Named("Bad") - .OnCreation("throw exception", obj => { throw new ApplicationException("Bad!"); }); + .OnCreation("throw exception", obj => { throw new Exception("Bad!"); }); }); -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -476,7 +482,7 @@

    Add Interception to a Single Instance

    -}); +}); diff --git a/interpreting-exceptions/index.html b/interpreting-exceptions/index.html index 3c9d8ee..32ed09e 100644 --- a/interpreting-exceptions/index.html +++ b/interpreting-exceptions/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Interpreting Exceptions - - - - - - - - - + StructureMap - Interpreting Exceptions + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Diagnostics

    -

    Previous

    Interception and Decorators

    - - -
    - - -
    -

    Interpreting Exceptions Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Interpreting Exceptions Edit on GitHub

    + +
    + +
    +

    Improving the exception messages was one of the primary goals of the big StructureMap 3.0 release. StructureMap exceptions should show a "StructureMap-specific stacktrace" describing where in the object graph StructureMap was when an exception occurred, while @@ -109,25 +107,25 @@

    Interpreting Exceptions Interception and Decorators + + + -

    -
    -
    +
    +
    +
    @@ -161,7 +159,7 @@

    Interpreting Exceptions - + - StructureMap - Configuring Lifecycles - - - - - - - - - + StructureMap - Configuring Lifecycles + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Custom Lifecycles

    -

    Previous

    Supported Lifecycles

    - - -
    - - -
    -

    Configuring Lifecycles Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Configuring Lifecycles Edit on GitHub

    + +
    + +
    +

    Unless designated otherwise, StructureMap uses Transient as the default scope for all configured Instance's.

    @@ -102,7 +100,7 @@

    Configuring Lifecycles - [Test] + [Fact] public void lifecycle_precedence() { var container = new Container(x => @@ -154,29 +152,30 @@

    Using Attributes

    [Singleton] // because the most wonderful thing about Tiggers is that I'm the only one.... public class Tigger { } +

    See Using Attributes for Configuration for information about adding your own custom attibutes for other lifecycles.

    -

    +
    -
    +
    - -
    -
    -
    +
    +
    +

    @@ -210,7 +209,7 @@

    Using Attributes

    -}); +}); diff --git a/object-lifecycle/custom-lifecycles/index.html b/object-lifecycle/custom-lifecycles/index.html index 2f7e34a..e662211 100644 --- a/object-lifecycle/custom-lifecycles/index.html +++ b/object-lifecycle/custom-lifecycles/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Custom Lifecycles - - - - - - - - - + StructureMap - Custom Lifecycles + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Generic Types

    -

    Previous

    Configuring Lifecycles

    - - -
    - - -
    -

    Custom Lifecycles Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Custom Lifecycles Edit on GitHub

    + +
    + +
    +

    Lifecycle's in StructureMap are pluggable. To create your own custom lifecycle, make an implementation of the ILifecycle interface like this one:

    
    @@ -138,25 +136,25 @@ 

    Custom Lifecycles Configuring Lifecycles + + + -

    -
    -
    +
    +
    +
    @@ -190,7 +188,7 @@

    Custom Lifecycles - + - StructureMap - Object Lifecycles - - - - - - - - - + StructureMap - Object Lifecycles + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Supported Lifecycles

    -

    Previous

    The Container

    - - -
    - - -
    -

    Object Lifecycles Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Object Lifecycles Edit on GitHub

    + +
    + +
    +

    One of the most valuable functions of using an IoC container tool is its ability to manage the object lifecycle (creating and disposing objects) and scoping (shared objects) of your system's services so you can focus on the actual functionality instead of busy work.

    @@ -152,25 +150,25 @@

    Motivation for Container Managed Scope

    how the ISingletonDependency object is built and certainly no coupling to the hard Singleton mechanics from the first sample that was so harmful in the past.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    +

    @@ -204,7 +202,7 @@

    Motivation for Container Managed Scope

    -}); +}); diff --git a/object-lifecycle/supported-lifecycles/index.html b/object-lifecycle/supported-lifecycles/index.html index a73d06e..86c0f87 100644 --- a/object-lifecycle/supported-lifecycles/index.html +++ b/object-lifecycle/supported-lifecycles/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Supported Lifecycles - - - - - - - - - + StructureMap - Supported Lifecycles + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Configuring Lifecycles

    -

    Previous

    Object Lifecycles

    - - -
    - - -
    -

    Supported Lifecycles Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Supported Lifecycles Edit on GitHub

    + +
    + +
    +

    Out of the box, the core StructureMap assembly supports these lifecycles:

      @@ -108,7 +106,7 @@

      Transient

      StructureMap's behavior for transient objects that implement IDisposable changed in 4.0 to introduce an "opt-in" tracking mode. Please see StructureMap and IDisposable for the details.

      The following unit test demonstrates how Transient lifecycles work in both root and nested containers.

      
      -        [Test]
      +        [Fact]
               public void Transient()
               {
                   var c = new Container(x => { x.For<IService>().Use<Service>().Transient(); });
      @@ -120,7 +118,7 @@ 

      Transient

      .ShouldNotBeTheSameAs(c.GetInstance<IService>()) .ShouldNotBeTheSameAs(c.GetInstance<IService>()); - // Within a nested container, 'Transient' now + // Within a nested container, 'Transient' now // means within the Nested Container. // A nested container is effectively one request using (var nested = c.GetNestedContainer()) @@ -178,24 +176,24 @@

      Transient

      } } - [Test] + [Fact] public void transient_scoped_Instance_is_built_once_per_resolution_to_the_Container() { var container = new Container(_ => { _.For<IUnitOfWork>().Use<DefaultUnitOfWork>(); }); - var cooridinator = container.GetInstance<WorkerCoordinator>(); + var coordinator = container.GetInstance<WorkerCoordinator>(); // The IUnitOfWork object instance is the same for // all the objects in the object graph that had // a constructor dependency on IUnitOfWork - cooridinator.Uow - .ShouldBeTheSameAs(cooridinator.Worker1.Uow); + coordinator.Uow + .ShouldBeTheSameAs(coordinator.Worker1.Uow); - cooridinator.Uow - .ShouldBeTheSameAs(cooridinator.Worker2.Uow); + coordinator.Uow + .ShouldBeTheSameAs(coordinator.Worker2.Uow); - cooridinator.Worker1.Uow - .ShouldBeTheSameAs(cooridinator.Worker2.Uow); + coordinator.Worker1.Uow + .ShouldBeTheSameAs(coordinator.Worker2.Uow); }
      @@ -205,7 +203,7 @@

      AlwaysUnique

      
      -        [Test]
      +        [Fact]
               public void Always_Unique()
               {
                   var c = new Container(x => { x.For<IService>().Use<Service>().AlwaysUnique(); });
      @@ -217,7 +215,7 @@ 

      AlwaysUnique

      .ShouldNotBeTheSameAs(c.GetInstance<IService>()) .ShouldNotBeTheSameAs(c.GetInstance<IService>()); - // Within a nested container, 'Transient' now + // Within a nested container, 'Transient' now // means within the Nested Container. // A nested container is effectively one request using (var nested = c.GetNestedContainer()) @@ -227,7 +225,7 @@

      AlwaysUnique

      .ShouldNotBeTheSameAs(nested.GetInstance<IService>()); } - // Even in a single request, + // Even in a single request, var holder = c.GetInstance<ServiceUserHolder>(); holder.Service.ShouldNotBeTheSameAs(holder.User.Service); } @@ -236,7 +234,7 @@

      AlwaysUnique

      Singleton

      StructureMap 3.0 fixed the dreaded singletons with nested container's bug that was so problematic in 2.6.

      
      -        [Test]
      +        [Fact]
               public void singletons_are_disposed_when_the_container_is_disposed()
               {
                   var container = new Container(_ =>
      @@ -260,6 +258,7 @@ 

      Singleton

      // the SingletonThing scoped object should be disposed singleton.WasDisposed.ShouldBeTrue(); } +

      Do note that objects created as the singleton scope will be disposed when the Container is disposed if they implement the IDisposable interface:

      @@ -306,24 +305,24 @@

      Singleton

      } } - [Test] + [Fact] public void transient_scoped_Instance_is_built_once_per_resolution_to_the_Container() { var container = new Container(_ => { _.For<IUnitOfWork>().Use<DefaultUnitOfWork>(); }); - var cooridinator = container.GetInstance<WorkerCoordinator>(); + var coordinator = container.GetInstance<WorkerCoordinator>(); // The IUnitOfWork object instance is the same for // all the objects in the object graph that had // a constructor dependency on IUnitOfWork - cooridinator.Uow - .ShouldBeTheSameAs(cooridinator.Worker1.Uow); + coordinator.Uow + .ShouldBeTheSameAs(coordinator.Worker1.Uow); - cooridinator.Uow - .ShouldBeTheSameAs(cooridinator.Worker2.Uow); + coordinator.Uow + .ShouldBeTheSameAs(coordinator.Worker2.Uow); - cooridinator.Worker1.Uow - .ShouldBeTheSameAs(cooridinator.Worker2.Uow); + coordinator.Worker1.Uow + .ShouldBeTheSameAs(coordinator.Worker2.Uow); }
      @@ -333,7 +332,7 @@

      ContainerScoped

      container, and every single nested container will build its own object instance.

      The acceptance test for ContainerScoped is shown below:

      
      -        [Test]
      +        [Fact]
               public void container_scoping_with_root_child_and_nested_container()
               {
                   var container = new Container(_ =>
      @@ -388,32 +387,27 @@ 

      ContainerScoped

      container.Dispose(); mainDisposable.WasDisposed.ShouldBeTrue(); } +

      ThreadLocal

      The ThreadLocalStorage based lifecycle is seldom used, but the easiest example of using it and explanation is the integration test:

      
      -    [TestFixture]
      +
           public class ThreadLocalStorageLifecycleTester
           {
      -        #region Setup/Teardown
      -
      -        [SetUp]
      -        public void SetUp()
      +        public ThreadLocalStorageLifecycleTester()
               {
                   _lifecycle = new ThreadLocalStorageLifecycle();
       
                   container = new Container(x => x.For<Rule>(Lifecycles.ThreadLocal).Use(() => new ColorRule("Red")));
               }
       
      -        #endregion
      -
               private ThreadLocalStorageLifecycle _lifecycle;
               private ColorRule _rule1;
               private ColorRule _rule2;
               private ColorRule _rule3;
               private Container container;
       
      -
               private void findRule1()
               {
                   _rule1 = container.GetInstance<Rule>().ShouldBeOfType<ColorRule>();
      @@ -447,7 +441,7 @@ 

      ThreadLocal

      _rule3.ShouldBeTheSameAs(rule); } - [Test] + [Fact] public void object_has_been_created() { container.Model.For<Rule>().Default.ObjectHasBeenCreated().ShouldBeFalse(); @@ -455,7 +449,7 @@

      ThreadLocal

      container.Model.For<Rule>().Default.ObjectHasBeenCreated().ShouldBeTrue(); } - [Test] + [Fact] public void FindUniqueInstancePerThread() { var t1 = new Thread(findRule1); @@ -490,45 +484,31 @@

      Legacy ASP.Net Lifecycles

    • Hybrid -- uses ThreadLocalStorage in the absence of an active HttpContext
    • HybridSession
    -
    
    -    public class AspNetRegistry : Registry
    -    {
    -        public AspNetRegistry()
    -        {
    -            For<IWeirdThing>().LifecycleIs<HttpContextLifecycle>();
    -            For<IGateway>().LifecycleIs<HybridLifecycle>();
    -            For<IRule>().LifecycleIs<HttpSessionLifecycle>();
    -            For<ICache>().LifecycleIs<HybridSessionLifecycle>();
    -        }
    -    }
    -
    -
    +

    Missing code sample 'AspNet-Lifecycles' -- Wait for ST to catch up reading samples or CTRL+SHIFT+R to force refresh

    If you do use any of the HttpContext lifecycles, make sure you also do:

    -
    
    -            HttpContextLifecycle.DisposeAndClearAll();
    -
    +

    Missing code sample 'clean-up-http-context' -- Wait for ST to catch up reading samples or CTRL+SHIFT+R to force refresh

    at the end of your HTTP request.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -562,7 +542,7 @@

    Legacy ASP.Net Lifecycles

    -}); +}); diff --git a/quickstart/index.html b/quickstart/index.html index b75d740..f3e5962 100644 --- a/quickstart/index.html +++ b/quickstart/index.html @@ -1,96 +1,94 @@ - + - StructureMap - A Gentle Quickstart - - - - - - - - - + StructureMap - A Gentle Quickstart + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Glossary

    -

    Previous

    Roadmap

    - - -
    - - -
    -

    A Gentle Quickstart Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    A Gentle Quickstart Edit on GitHub

    + +
    + +
    +

    The first thing you should know is that StructureMap (and other IoC tools like it) are designed to make compositional and modular software designs easier to build by offloading the grubby mechanics of @@ -188,25 +186,25 @@

    Need Help?

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -240,7 +238,7 @@

    Need Help?

    -}); +}); diff --git a/registration/attributes/index.html b/registration/attributes/index.html index 7b95c09..11bdf60 100644 --- a/registration/attributes/index.html +++ b/registration/attributes/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Using Attributes for Configuration - - - - - - - - - + StructureMap - Using Attributes for Configuration + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Resolving Services

    -

    Previous

    Replace or Clear Out Previous Registrations

    - - -
    - - -
    -

    Using Attributes for Configuration Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Using Attributes for Configuration Edit on GitHub

    + +
    + +
    +

    In the early days of StructureMap we had several attibutes for basic configuration that we'd just as soon forget ever existed. Further more, the StructureMap strongly believes that the usage of StructureMap should have as little impact on application code as possible -- and forcing users to spray .Net attributes all over @@ -175,6 +173,7 @@

    Attribute Targeting Plugin Type or Concrete Type

    public interface ITeamCache { } public class TeamCache : ITeamCache { } + public class OtherTeamCache : ITeamCache { } public interface ITeam { } @@ -183,6 +182,7 @@

    Attribute Targeting Plugin Type or Concrete Type

    [Singleton] // This specific type will be a singleton public class Chiefs : ITeam { } +

    Attribute Targeting Constructor Parameters or Setter Properties

    As an example, let's say that you want a new attribute type that can decorate either properties or constructor parameters @@ -212,6 +212,7 @@

    Attribute Targeting Constructor Parameters or Setter Properties

    instance.Dependencies.AddForConstructorParameter(parameter, value); } } +

    To test out the new attribute above, say we have a concrete type like this one that we decorate with the new [AppSetting] attribute:

    @@ -228,10 +229,11 @@

    Attribute Targeting Constructor Parameters or Setter Properties

    Name = name; } } +

    The following unit test demonstrates our new custom [AppSetting] attribute in action:

    
    -        [Test]
    +        [Fact]
             public void using_parameter_and_property_attibutes()
             {
                 System.Configuration.ConfigurationManager.AppSettings["name"] = "Jeremy";
    @@ -248,6 +250,7 @@ 

    Attribute Targeting Constructor Parameters or Setter Properties

    Debug.WriteLine(container.Model.For<AppSettingTarget>().Default.DescribeBuildPlan()); } +

    The build plan for AppSettingTarget is determined by the active StructureMap container to be this:

    @@ -271,25 +274,25 @@

    Built In Attributes

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -323,7 +326,7 @@

    Built In Attributes

    -}); +}); diff --git a/registration/auto-registration-and-conventions/index.html b/registration/auto-registration-and-conventions/index.html index 5f3251e..428d32d 100644 --- a/registration/auto-registration-and-conventions/index.html +++ b/registration/auto-registration-and-conventions/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Auto-Registration and Conventions - - - - - - - - - + StructureMap - Auto-Registration and Conventions + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Working with IConfiguredInstance

    -

    Previous

    Inline Dependencies

    - - -
    - - -
    -

    Auto-Registration and Conventions Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Auto-Registration and Conventions Edit on GitHub

    + +
    + +
    +

    StructureMap has rich support for registering types by scanning assemblies and applying conventional registrations. @@ -136,7 +134,7 @@

    Scan the Calling Assembly

    Note if you have other registries, StructureMap will not automatically find them.

    
    -        [Test]
    +        [Fact]
             public void scan_but_ignore_registries_by_default()
             {
                 Scan(x => { x.TheCallingAssembly(); });
    @@ -151,7 +149,7 @@ 

    Scan for Registries

    StructureMap can automatically include other registries with theLookForRegistries method.

    
    -        [Test]
    +        [Fact]
             public void Search_for_registries_when_explicitly_told()
             {
                 Scan(x =>
    @@ -168,7 +166,7 @@ 

    Scan for Registries

    Search for Assemblies on the File System

    StructureMap provides facilities for registering types by finding assemblies in the application bin path:

    
    -        [Test]
    +        [Fact]
             public void scan_all_assemblies_in_a_folder()
             {
                 Scan(x => x.AssembliesFromPath(assemblyScanningFolder));
    @@ -177,7 +175,7 @@ 

    Search for Assemblies on the File System

    shouldNotHaveFamilyWithSameName<IDefinedInExe>(); } - [Test] + [Fact] public void scan_all_assemblies_in_application_base_directory() { Scan(x => x.AssembliesFromApplicationBaseDirectory()); @@ -185,12 +183,13 @@

    Search for Assemblies on the File System

    shouldHaveFamilyWithSameName<IWorker>(); shouldNotHaveFamilyWithSameName<IDefinedInExe>(); } +

    Do note that StructureMap 4.0 does not search for .exe files in the assembly search. The StructureMap team felt this was problematic and "nobody would ever actually want to do that." We were wrong, and due to many user requests, you can now opt in to scanning .exe files with a new public method on AssemblyScanner shown below:

    
    -        [Test]
    +        [Fact]
             public void scan_all_assemblies_in_a_folder_including_exe()
             {
                 Scan(x => x.AssembliesAndExecutablesFromPath(assemblyScanningFolder));
    @@ -200,7 +199,8 @@ 

    Search for Assemblies on the File System

    shouldHaveFamilyWithSameName<IDefinedInExe>(); } - [Test] + + [Fact] public void scan_all_assemblies_in_application_base_directory_including_exe() { Scan(x => x.AssembliesAndExecutablesFromApplicationBaseDirectory()); @@ -209,6 +209,7 @@

    Search for Assemblies on the File System

    shouldHaveFamilyWithSameName<IWorker>(); shouldHaveFamilyWithSameName<IDefinedInExe>(); } +

    Do be aware that while this technique is very powerful for extensibility, it's been extremely problematic for some folks in the past. The StructureMap team's recommendation for using this feature is to:

    @@ -227,7 +228,7 @@

    Excluding Types

    Excluding additional types or namespaces is as easy as calling the corresponding method again.

    
    -        [Test]
    +        [Fact]
             public void use_a_single_exclude_of_type()
             {
                 Scan(x =>
    @@ -240,8 +241,7 @@ 

    Excluding Types

    shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>(); } - - [Test] + [Fact] public void use_a_single_exclude2() { Scan(x => @@ -254,8 +254,7 @@

    Excluding Types

    shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>(); } - - [Test] + [Fact] public void use_a_single_exclude3() { Scan(x => @@ -313,7 +312,7 @@

    Custom Registration Conventions

    } } - [Test] + [Fact] public void use_custom_registration_convention() { var container = new Container(_ => @@ -342,12 +341,14 @@

    The Default ISomething/Something Convention

    the I[Something]/[Something] naming convention as shown in this sample:

    
             public interface ISpaceship { }
    +
             public class Spaceship : ISpaceship { }
     
             public interface IRocket { }
    +
             public class Rocket : IRocket { }
     
    -        [Test]
    +        [Fact]
             public void default_scanning_in_action()
             {
                 var container = new Container(_ =>
    @@ -362,15 +363,17 @@ 

    The Default ISomething/Something Convention

    container.GetInstance<ISpaceship>().ShouldBeOfType<Spaceship>(); container.GetInstance<IRocket>().ShouldBeOfType<Rocket>(); } +

    The StructureMap team contains some VB6 veterans who hate Hungarian Notation, but can't shake the "I" nomenclature.

    Registering the Single Implementation of an Interface

    To tell StructureMap to automatically register any interface that only has one concrete implementation, use this method:

    
             public interface ISong { }
    +
             public class TheOnlySong : ISong { }
     
    -        [Test]
    +        [Fact]
             public void only_implementation()
             {
                 var container = new Container(_ =>
    @@ -385,17 +388,20 @@ 

    Registering the Single Implementation of an Interface

    container.GetInstance<ISong>() .ShouldBeOfType<TheOnlySong>(); } +

    Register all Concrete Types of an Interface

    To add all concrete types that can be cast to a named plugin type, use this syntax:

    
             public interface IFantasySeries { }
    +
             public class WheelOfTime : IFantasySeries { }
    +
             public class GameOfThrones : IFantasySeries { }
    -        public class BlackCompany : IFantasySeries { }
     
    +        public class BlackCompany : IFantasySeries { }
     
    -        [Test]
    +        [Fact]
             public void register_all_types_of_an_interface()
             {
                 var container = new Container(_ =>
    @@ -408,7 +414,7 @@ 

    Register all Concrete Types of an Interface

    // or - x.AddAllTypesOf(typeof (IFantasySeries)) + x.AddAllTypesOf(typeof(IFantasySeries)) .NameBy(type => type.Name.ToLower()); }); }); @@ -418,6 +424,7 @@

    Register all Concrete Types of an Interface

    .OrderBy(x => x.Name) .ShouldHaveTheSameElementsAs(typeof(BlackCompany), typeof(GameOfThrones), typeof(WheelOfTime)); } +

    Note, "T" does not have to be an interface, it's all based on the ability to cast a concrete type to the "T"

    Generic Types

    @@ -434,31 +441,31 @@

    Register Concrete Types against the First Interface

    o.TheCallingAssembly(); o.RegisterConcreteTypesAgainstTheFirstInterface(); - o.Exclude(t => t.CanBeCastTo(typeof (IGateway))); + o.Exclude(t => t.CanBeCastTo(typeof(IGateway))); }); });
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -492,7 +499,7 @@

    Register Concrete Types against the First Interface

    -}); +}); diff --git a/registration/changing-configuration-at-runtime/index.html b/registration/changing-configuration-at-runtime/index.html index da0604c..1d0c582 100644 --- a/registration/changing-configuration-at-runtime/index.html +++ b/registration/changing-configuration-at-runtime/index.html @@ -1,102 +1,100 @@ - + - StructureMap - Changing Configuration at Runtime - - - - - - - - - + StructureMap - Changing Configuration at Runtime + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    On Missing Family Policies

    -

    Previous

    Construction Policies

    - - -
    - - -
    -

    Changing Configuration at Runtime Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Changing Configuration at Runtime Edit on GitHub

    + +
    + +
    +

    If you need to add or change configuration to an existing StructureMap Container object, you can use the IContainer.Configure() method to add or change your container at runtime as shown below:

    
    -        [Test]
    +        [Fact]
             public void change_default_in_an_existing_container()
             {
                 var container = new Container(x => { x.For<IFoo>().Use<AFoo>(); });
    @@ -128,25 +126,25 @@ 

    Best Practices

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -180,7 +178,7 @@

    Best Practices

    -}); +}); diff --git a/registration/clear-or-replace/index.html b/registration/clear-or-replace/index.html index 635718a..e12a351 100644 --- a/registration/clear-or-replace/index.html +++ b/registration/clear-or-replace/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Replace or Clear Out Previous Registrations - - - - - - - - - + StructureMap - Replace or Clear Out Previous Registrations + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Using Attributes for Configuration

    -

    Previous

    Registering Existing Objects

    - - -
    - - -
    -

    Replace or Clear Out Previous Registrations Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Replace or Clear Out Previous Registrations Edit on GitHub

    + +
    + +
    +

    Several members of the StructureMap team were also very active in a now semi-defunct web framework called FubuMVC that was built with quite a bit of extensibility in mind. One of the extensibility mechanisms that was successful in FubuMVC was the ability for applications or addon libraries to swap out the default services in the main StructureMap application container.

    The approach we took for this extensibility was what I flippantly call the "Mongolian BBQ" architecture. The framework should take the application specific registrations, the framework defaults, and all the discovered addons and figure out how to order the registrations to enforce the following levels of registration precedence:

    @@ -118,25 +116,26 @@

    Replace or Clear Out Previous Registrations - [Test] + [Fact] public void clear_all_in_action() { var container = new Container(_ => { _.For<IWidget>().Use<AWidget>(); - _.IncludeRegistry<ImportantClientServices>(); }); container.GetInstance<IWidget>() .ShouldBeOfType<ImportantClientWidget>(); - Debug.WriteLine(container.WhatDoIHave(pluginType:typeof(IWidget))); + Debug.WriteLine(container.WhatDoIHave(pluginType: typeof(IWidget))); } +

    If you were to check the WhatDoIHave() view for IWidget, you would see only the ImportantClientWidget:

    @@ -148,25 +147,25 @@ 

    Replace or Clear Out Previous Registrations Registering Existing Objects + + + -

    -
    -
    +
    +
    +
    @@ -200,7 +199,7 @@

    Replace or Clear Out Previous Registrations - + - StructureMap - Working with IConfiguredInstance - - - - - - - - - + StructureMap - Working with IConfiguredInstance + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Construction Policies

    -

    Previous

    Auto-Registration and Conventions

    - - -
    - - -
    -

    Working with IConfiguredInstance Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Working with IConfiguredInstance Edit on GitHub

    + +
    + +
    +

    The most common way for StructureMap to build or resolve a requested object is to build a concrete type directly by calling a public constructor function and optionally filling values in public setter properties. For this type of object construction, StructureMap exposes the IConfiguredInstance interface as a means of querying and modifying how a concrete type will be @@ -175,7 +173,7 @@

    Changing the Instance Lifecycle

    instance.Singleton(); // or supply an ILifecycle type - instance.SetLifecycleTo<HttpContextLifecycle>(); + instance.SetLifecycleTo<ThreadLocalStorageLifecycle>(); // or supply an ILifecycle object instance.SetLifecycleTo(new Lifecycles_Samples.MyCustomLifecycle()); @@ -193,17 +191,17 @@

    Reflecting over Constructor Parameters

    } } - [Test] + [Fact] public void reflecting_over_constructor_args() { IConfiguredInstance instance = new SmartInstance<GuyWithArguments>() // I'm just forcing it to assign the constructor function .SelectConstructor(() => new GuyWithArguments(null, null)); - instance.Constructor.GetParameters().Select(x => x.Name) .ShouldHaveTheSameElementsAs("widget", "rule"); } +

    The constructor function selection process takes place as the very first step in creating a build plan and will be available in any kind of construction policy or configuration attribute on @@ -218,15 +216,16 @@

    Reflecting over Setter Properties

    public Rule Rule { get; private set; } } - [Test] + [Fact] public void get_settable_properties() { - IConfiguredInstance instance + IConfiguredInstance instance = new ConfiguredInstance(typeof(GuyWithProperties)); instance.SettableProperties() .Single().Name.ShouldBe("Widget"); } +

    Working with Dependencies

    The IConfiguredInstance.Dependencies property is a collection of Argument objects that model inline dependencies. A @@ -255,10 +254,10 @@

    Add a Dependency for a Setter Property

    that can be cast to the property type or an Instance object that returns a type that can be cast to the property type.

    With a value:

    
    -        [Test]
    +        [Fact]
             public void dependency_with_setter_with_value()
             {
    -            var instance 
    +            var instance
                     = new ConfiguredInstance(typeof(GuyWithProperties));
                 var prop = instance.PluggedType.GetProperty("Widget");
     
    @@ -270,10 +269,11 @@ 

    Add a Dependency for a Setter Property

    container.GetInstance<GuyWithProperties>(instance) .Widget.ShouldBeTheSameAs(myWidget); } +

    With an Instance for the dependency value:

    
    -        [Test]
    +        [Fact]
             public void dependency_with_setter_with_instance()
             {
                 var instance
    @@ -288,6 +288,7 @@ 

    Add a Dependency for a Setter Property

    container.GetInstance<GuyWithProperties>(instance) .Widget.ShouldBeOfType<AWidget>(); } +

    Add a Dependency for a Constructor Parameter

    Likewise, you can add a dependency for a specific constructor parameter as either the actual value or an Instance object with the AddForConstructorParameter helper method:

    @@ -302,7 +303,7 @@

    Add a Dependency for a Constructor Parameter

    } } - [Test] + [Fact] public void specify_dependency_by_constructor_parameter() { var instance = ConstructorInstance @@ -311,16 +312,16 @@

    Add a Dependency for a Constructor Parameter

    var parameter = instance.Constructor.GetParameters().Single(); parameter.Name.ShouldBe("connectionString"); - var connString = + var connString = "I haven't used sql server in years and I don't remember what connection strings look like"; instance.Dependencies.AddForConstructorParameter(parameter, connString); - var guy = new Container().GetInstance<GuyWithDatabaseConnection>(instance); guy.ConnectionString.ShouldBe(connString); } +

    Adding Interceptors

    You can add interceptors directly to a single IConfiguredInstance with code like this:

    @@ -336,10 +337,10 @@

    Adding Interceptors

    } } - [Test] + [Fact] public void add_interceptor() { - var interceptor = + var interceptor = new ActivatorInterceptor<SimpleWidget>(w => w.Intercept()); var instance = new SmartInstance<SimpleWidget>(); @@ -348,29 +349,30 @@

    Adding Interceptors

    new Container().GetInstance<SimpleWidget>(instance) .WasIntercepted.ShouldBeTrue(); } +

    See Interception and Decorators for more information.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    +

    @@ -404,7 +406,7 @@

    Adding Interceptors

    -}); +}); diff --git a/registration/constructor-selection/index.html b/registration/constructor-selection/index.html index 6f306c7..958f4a0 100644 --- a/registration/constructor-selection/index.html +++ b/registration/constructor-selection/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Constructor Selection - - - - - - - - - + StructureMap - Constructor Selection + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Fallback Services

    -

    Previous

    On Missing Family Policies

    - - -
    - - -
    -

    Constructor Selection Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Constructor Selection Edit on GitHub

    + +
    + +
    +

    StructureMap 3.* greatly improves the control over the selection of constructor functions to build concrete types by allowing users to override the constructor selection on specific Instance's and register custom rules for @@ -120,11 +118,10 @@

    Greediest Constructor

    public GreaterThanRule(IWidget widget, Rule rule) { - } } - [Test] + [Fact] public void using_the_greediest_ctor() { var container = new Container(_ => @@ -155,11 +152,10 @@

    Greediest Constructor

    public DbContext() : this("default value") { - } } - [Test] + [Fact] public void should_bypass_ctor_with_unresolvable_simple_args() { var container = new Container(); @@ -167,7 +163,7 @@

    Greediest Constructor

    .ConnectionString.ShouldBe("default value"); } - [Test] + [Fact] public void should_use_greediest_ctor_that_has_all_of_simple_dependencies() { var container = new Container(_ => @@ -179,6 +175,7 @@

    Greediest Constructor

    container.GetInstance<DbContext>() .ConnectionString.ShouldBe("not the default"); } +

    Explicitly Selecting a Constructor

    To override the constructor selection explicitly on a case by case basis, you @@ -196,11 +193,11 @@

    Explicitly Selecting a Constructor

    public Thingie(IWidget widget, IService service) { - Assert.Fail("I should not have been called"); + Assert.True(false, "I should not have been called"); } } - [Test] + [Fact] public void override_the_constructor_selection() { var container = new Container(_ => @@ -210,7 +207,7 @@

    Explicitly Selecting a Constructor

    _.ForConcreteType<Thingie>().Configure // StructureMap parses the expression passed - // into the method below to determine the + // into the method below to determine the // constructor .SelectConstructor(() => new Thingie(null)); }); @@ -240,11 +237,11 @@

    [DefaultConstructor] Attribute

    public AttributedThing(IWidget widget, IService service) { - Assert.Fail("I should not have been called"); + Assert.True(false, "I should not have been called"); } } - [Test] + [Fact] public void select_constructor_by_attribute() { var container = new Container(_ => { _.For<IWidget>().Use<AWidget>(); }); @@ -274,7 +271,7 @@

    Custom Constructor Selection Rule

    public BaseThing(IWidget widget, IService service) { - Assert.Fail("I should not have been called"); + Assert.True(false, "I should not have been called"); } } @@ -312,14 +309,14 @@

    Custom Constructor Selection Rule

    // just return null to denote "not applicable" if (!pluggedType.CanBeCastTo<BaseThing>()) return null; - return pluggedType.GetConstructor(new[] {typeof (IWidget)}); + return pluggedType.GetConstructor(new[] { typeof(IWidget) }); } }

    Finally, you can register your custom rule as shown below:

    
    -        [Test]
    +        [Fact]
             public void use_a_custom_constructor_selector()
             {
                 var container = new Container(_ =>
    @@ -339,25 +336,25 @@ 

    Custom Constructor Selection Rule

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -391,7 +388,7 @@

    Custom Constructor Selection Rule

    -}); +}); diff --git a/registration/existing-objects/index.html b/registration/existing-objects/index.html index ff87d94..a027b96 100644 --- a/registration/existing-objects/index.html +++ b/registration/existing-objects/index.html @@ -1,107 +1,106 @@ - + - StructureMap - Registering Existing Objects - - - - - - - - - + StructureMap - Registering Existing Objects + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Replace or Clear Out Previous Registrations

    -

    Previous

    Fallback Services

    - - -
    - - -
    -

    Registering Existing Objects Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Registering Existing Objects Edit on GitHub

    + +
    + +
    +

    It's frequently common to register existing objects with a StructureMap Container and there are overloads of the Registry.For().Use(object) and Registry.For().Add(object) methods to do just that:

    
    -        [Test]
    +        [Fact]
             public void should_be_able_to_resolve_from_the_generic_family_expression()
             {
                 var widget = new AWidget();
    -            var container = new Container(x => x.For(typeof (IWidget)).Use(widget).Named("mine"));
    +            var container = new Container(x => x.For(typeof(IWidget)).Use(widget).Named("mine"));
     
                 container.GetInstance<IWidget>("mine").ShouldBeTheSameAs(widget);
             }
    +
     

    Injecting an existing object into the Container makes it a de facto singleton, but the Container treats it with a special scope called ObjectLifecycle if you happen to look into the WhatDoIHave() diagnostics.

    @@ -109,25 +108,25 @@

    Registering Existing Objects Fallback Services + + + -

    -
    -
    +
    +
    +
    @@ -161,7 +160,7 @@

    Registering Existing Objects - + - StructureMap - Fallback Services - - - - - - - - - + StructureMap - Fallback Services + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Registering Existing Objects

    -

    Previous

    Constructor Selection

    - - -
    - - -
    -

    Fallback Services Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Fallback Services Edit on GitHub

    + +
    + +
    +

    The following is a technique that was stolen from FubuMVC where we used the idea of default or "fallback" registrations to make it mechanically simple for the core framework to declare @@ -119,7 +117,37 @@

    Fallback Services + [AttributeUsage(AttributeTargets.Assembly)] + public class ProductModuleAttribute : Attribute + { + } + + public class ApplicationRegistry : Registry + { + public ApplicationRegistry() + { + // Use the default services as fallbacks + IncludeRegistry<DefaultServices>(); + + // Dependending on what assemblies are present, + // this might find specific registrations that + // will take precedence over the UseIfNone() + // registrations in DefaultServices + Scan(_ => + { + _.AssembliesFromApplicationBaseDirectory( + assem => assem.HasAttribute<ProductModuleAttribute>()); + + _.LookForRegistries(); + }); + } + } + + [Fact] public void see_use_if_none_in_action() { var container1 = Container.For<DefaultServices>(); @@ -129,7 +157,6 @@

    Fallback Services -

    In application usage, you would add the default UseIfNone() registrations, and optionally pick -up additional extension Registry objects from extension assemblies as shown in this example:

    -
    
    -        [AttributeUsage(AttributeTargets.Assembly)]
    -        public class ProductModuleAttribute : Attribute { }
     
    -        public class ApplicationRegistry : Registry
    -        {
    -            public ApplicationRegistry()
    -            {
    -                // Use the default services as fallbacks
    -                IncludeRegistry<DefaultServices>();
    -
    -                // Dependending on what assemblies are present,
    -                // this might find specific registrations that
    -                // will take precedence over the UseIfNone() 
    -                // registrations in DefaultServices
    -                Scan(_ =>
    -                {
    -                    _.AssembliesFromApplicationBaseDirectory(assem =>
    -                    {
    -                        return assem.HasAttribute<ProductModuleAttribute>();
    -                    });
    -
    -                    _.LookForRegistries();
    -                });
    -            }
    -        }
     
    -

    +
    -
    +
    -
    -
    -
    -
    +
    +
    +

    @@ -228,7 +227,7 @@

    Fallback Services - + - StructureMap - Registration - - - - - - - - - + StructureMap - Registration + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Registry DSL

    -

    Previous

    Setter Injection

    - - -
    - - -
    -

    Registration Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Registration Edit on GitHub

    + +
    + +
    +

    As of the 3.0 release, StructureMap provides a streamlined fluent interface called the Registry DSL to configure a StructureMap Container with both explicit registrations and conventional auto-registrations. StructureMap no longer supports Xml configuration or MEF-style attribute configuration -- but there is some facility for rolling your own attribute-based configuration support.

    @@ -191,8 +189,8 @@

    Registration -

    Sometimes classes need to be suplied with some primitive value in its constructor. For example the System.Data.SqlClient.SqlConnection needs to be supplied with the connection string in its constructor. No problem, just set up the value of the constructor argument in the bootstrapping:

    +

    We instruct the scanner to scan through the calling assembly with default conventions on. This will find and register the default instance for IFoo and IBar which are obviously the concrete types Foo and Bar. Now whenever you add an additional interface IMoreFoo and a class MoreFoo to your application's code base, it's automatically picked up by the scanner.

    +

    Sometimes classes need to be supplied with some primitive value in its constructor. For example the System.Data.SqlClient.SqlConnection needs to be supplied with the connection string in its constructor. No problem, just set up the value of the constructor argument in the bootstrapping:

    
                 var container = new Container(c =>
                 {
    @@ -201,28 +199,28 @@ 

    Registration Bar class, or do depend on other types like the Foo class needs an instance of IBar. In our last example we have seen configuration for objects that needs some primitive types like strings in its constructor function.

    +

    So far you have seen an couple of ways to work with the <linkto:registration/registry-dsl]> and configure a Container object. We have seen examples of configuration that allow us to build objects that don't depend on anything like the Bar class, or do depend on other types like the Foo class needs an instance of IBar. In our last example we have seen configuration for objects that need some primitive types like strings in its constructor function.

    -

    +
    -
    +
    -
    -
    -
    -
    +
    +
    + @@ -256,7 +254,7 @@

    Registration - + - StructureMap - Inline Dependencies - - - - - - - - - + StructureMap - Inline Dependencies + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Auto-Registration and Conventions

    -

    Previous

    Registry DSL

    - - -
    - - -
    -

    Inline Dependencies Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Inline Dependencies Edit on GitHub

    + +
    + +
    +

    While you generally allow StructureMap to just use auto-wiring to fill the dependencies of a concrete type, there are times when you may want to explicitly configure individual dependencies on a case by case basis. In the case of primitive types @@ -110,7 +108,7 @@

    Inline Dependencies - [Test] + [Fact] public void inline_usage_of_primitive_constructor_argument() { var container = new Container(_ => @@ -272,7 +270,7 @@

    Specifying the Argument Name

    public DualConditionRuleRegistry() { // In this case, because DualConditionRule - // has two different + // has two different For<IEventRule>().Use<DualConditionRule>() .Ctor<ICondition>("first").Is<Condition1>() .Ctor<ICondition>("second").Is<Condition2>(); @@ -390,15 +388,15 @@

    Programmatic Configuration outside of the Registry DSL

    { public OpenTypesRegistry() { - var instance = new ConstructorInstance(typeof (EventRule<>)); + var instance = new ConstructorInstance(typeof(EventRule<>)); // By name - instance.Dependencies.Add("action", typeof (Action1<>)); + instance.Dependencies.Add("action", typeof(Action1<>)); // Everything else is syntactical sugur over this: instance.Dependencies.Add(new Argument { - Type = typeof (IAction<>), // The dependency type + Type = typeof(IAction<>), // The dependency type Name = "action", // The name of the dependency, either // a constructor argument name or // the name of a setter property @@ -406,7 +404,7 @@

    Programmatic Configuration outside of the Registry DSL

    // Specify the actual dependency // This can be either a concrete type, the prebuilt value, // or an Instance - Dependency = typeof (Action1<>) + Dependency = typeof(Action1<>) }); } } @@ -460,25 +458,25 @@

    Programmatic Configuration outside of the Registry DSL

    -

    +
    -
    +
    -
    -
    -
    -
    +
    +
    + @@ -512,7 +510,7 @@

    Programmatic Configuration outside of the Registry DSL

    -}); +}); diff --git a/registration/on-missing-family-policies/index.html b/registration/on-missing-family-policies/index.html index 6fc6de2..ff46db8 100644 --- a/registration/on-missing-family-policies/index.html +++ b/registration/on-missing-family-policies/index.html @@ -1,96 +1,94 @@ - + - StructureMap - On Missing Family Policies - - - - - - - - - + StructureMap - On Missing Family Policies + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Constructor Selection

    -

    Previous

    Changing Configuration at Runtime

    - - -
    - - -
    -

    On Missing Family Policies Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + + -
    +
    +
    + @@ -344,7 +342,7 @@

    Using a Custom IFamilyPolicy" id="custom">

    -}); +}); diff --git a/registration/policies/index.html b/registration/policies/index.html index 61fe05b..7fa8fda 100644 --- a/registration/policies/index.html +++ b/registration/policies/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Construction Policies - - - - - - - - - + StructureMap - Construction Policies + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Changing Configuration at Runtime

    -

    Previous

    Working with IConfiguredInstance

    - - -
    - - -
    -

    Construction Policies Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Construction Policies Edit on GitHub

    + +
    + +
    +

    StructureMap has long supported conventional policies for registration based on type scanning and 3.0 introduced cleaner mechanisms for interception policies. @@ -189,6 +187,7 @@

    Example 1: Constructor arguments

    ConnectionString = connectionString; } } +

    Instead of explicitly configuring every single concrete class in StructureMap with that inline constructor argument, @@ -213,10 +212,11 @@

    Example 1: Constructor arguments

    return "the connection string"; } } +

    Now, let's use that policy against the types that need "connectionString" and see what happens:

    
    -        [Test]
    +        [Fact]
             public void use_the_connection_string_policy()
             {
                 var container = new Container(_ =>
    @@ -230,6 +230,7 @@ 

    Example 1: Constructor arguments

    container.GetInstance<ConnectedThing>() .ConnectionString.ShouldBe("the connection string"); } +

    Years ago StructureMap was knocked by an "IoC expert" for not having this functionality. I said at the time -- and still would -- that I would strongly recommend that you simply don't directly @@ -258,6 +259,7 @@

    Example 2: Connecting to Databases based on Parameter Name

    return string.Format("ConnectionString: {0}", ConnectionString); } } +

    For a registration policy, let's say that the parameter name of an IDatabase dependency in a constructor function should match an identifier of one of the registered IDatabase services. @@ -268,7 +270,7 @@

    Example 2: Connecting to Databases based on Parameter Name

    protected override void apply(Type pluginType, IConfiguredInstance instance) { instance.Constructor.GetParameters() - .Where(x => x.ParameterType == typeof (IDatabase)) + .Where(x => x.ParameterType == typeof(IDatabase)) .Each(param => { // Using ReferencedInstance here tells StructureMap @@ -278,6 +280,7 @@

    Example 2: Connecting to Databases based on Parameter Name

    }); } } +

    And because I'm generally pretty boring about picking test data names, let's say that two of our databases are named "red" and "green" with this container registration below:

    @@ -289,7 +292,7 @@

    Example 2: Connecting to Databases based on Parameter Name

    _.For<IDatabase>().Add<Database>().Named("green") .Ctor<string>("connectionString").Is("*green*"); - + _.Policies.Add<InjectDatabaseByName>(); }); @@ -328,8 +331,10 @@

    Example 2: Connecting to Databases based on Parameter Name

    // and ctor params. The easiest thing is to just make // setters private public IDatabase Green { get; private set; } + public IDatabase Red { get; private set; } } +

    Finally, we can exercise our new policy and see it in action:

    
    @@ -369,12 +374,13 @@ 

    Example 3: Make objects singletons based on type name

    } } } +

    Now, let's say that we have an interface named IWidgets and a single implementation called WidgetCache that should track our widgets in the application. Using our new policy, we should see WidgetCache being made a singleton:

    
    -        [Test]
    +        [Fact]
             public void set_cache_to_singleton()
             {
                 var container = new Container(_ =>
    @@ -389,33 +395,34 @@ 

    Example 3: Make objects singletons based on type name

    container.GetInstance<IWidgets>() .ShouldBeTheSameAs(container.GetInstance<IWidgets>()); - // Now that the policy has executed, we + // Now that the policy has executed, we // can verify that WidgetCache is a SingletonThing container.Model.For<IWidgets>().Default .Lifecycle.ShouldBeOfType<SingletonLifecycle>(); } +
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -449,7 +456,7 @@

    Example 3: Make objects singletons based on type name

    -}); +}); diff --git a/registration/registry-dsl/index.html b/registration/registry-dsl/index.html index 1f54eb9..3662a71 100644 --- a/registration/registry-dsl/index.html +++ b/registration/registry-dsl/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Registry DSL - - - - - - - - - + StructureMap - Registry DSL + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Inline Dependencies

    -

    Previous

    Registration

    - - -
    - - -
    -

    Registry DSL Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Registry DSL Edit on GitHub

    + +
    + +
    +

    Creating Registry classes is the recommended way of using the Registry DSL.

    The Registry DSL is mostly a fluent interface with some nested closure @@ -118,7 +116,7 @@

    Including Registries

    When you set up a Container, you need to simply direct the Container to use the configuration in that Registry class:

    
    -        [Test]
    +        [Fact]
             public void include_a_registry()
             {
                 var registry = new Registry();
    @@ -172,7 +170,7 @@ 

    For().Use()

    // Also rare, but you can supply an Instance object // yourself for special needs For<IWidget>().UseInstance(new MySpecialInstance()); - + // If you're registering an open generic type // or you just have Type objects, use this syntax For(typeof (IService<>)).Use(typeof (Service<>)); @@ -183,7 +181,7 @@

    For().Use()

    }

    For().Add()

    -

    To register additional Instance's for a plugin type, use one of the overloads of For().Add():

    +

    To register additional Instances for a plugin type, use one of the overloads of For().Add():

    
         public class AdditionalRegistrations : Registry
         {
    @@ -213,7 +211,7 @@ 

    For().Add()

    }

    Add Many Registrations with For().AddInstances()

    -

    If you need to add several Instance's to a single plugin type, the AddInstances() syntax +

    If you need to add several Instances to a single plugin type, the AddInstances() syntax shown below may be quicker and easier to use:

    
     
    @@ -237,19 +235,19 @@ 

    Named Instances

    When you have multiple implementations of an interface, it can often be useful to name instances. To retrieve a specific implementation:

    
    -        [Test]
    +        [Fact]
             public void SimpleCaseWithNamedInstance()
             {
                 container = new Container(x => { x.For<IWidget>().Add<AWidget>().Named("MyInstance"); });
                 // retrieve an instance by name
    -            var widget = (AWidget) container.GetInstance<IWidget>("MyInstance");
    +            var widget = (AWidget)container.GetInstance<IWidget>("MyInstance");
                 widget.ShouldNotBeNull();
             }
     
     

    You can also register named instances with the following shorthand:

    
    -        [Test]
    +        [Fact]
             public void A_concrete_type_is_available_by_name_when_it_is_added_by_the_shorthand_mechanism()
             {
                 IContainer container = new Container(r => r.For<IAddTypes>().AddInstances(x =>
    @@ -268,25 +266,25 @@ 

    Named Instances

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -320,7 +318,7 @@

    Named Instances

    -}); +}); diff --git a/release-notes/index.html b/release-notes/index.html index 4009264..8e3bfd4 100644 --- a/release-notes/index.html +++ b/release-notes/index.html @@ -1,102 +1,116 @@ - + - StructureMap - Release Notes - - - - - - - - - + StructureMap - Release Notes + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Custom Instance Types

    -

    Previous

    History

    - - -
    - - -
    -

    Release Notes Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Release Notes Edit on GitHub

    + +
    + +
    +

    StructureMap is attempting to follow a strict SemVer versioning policy.

    +

    Release Notes 4.3

    +

    See the closed GitHub issues for +a complete list of changes.

    +
      +
    • Converts the codebase to using the new dotnet CLI tools
    • +
    • Targets .Net 4.5, Netstandard 1.3, and Netstandard 1.5
    • +
    • Performance improvement for some IContainer.With() usages
    • +
    +

    Release Notes 4.2

    +
      +
    • Added the "disposal lock" feature to prevent a Container from being erroneously disposed
    • +

    Release Notes 4.1

    4.1 was mostly a bugfix release, but also included some new public API calls for type scanning discovery from *.exe files. See the closed GitHub issues for details.

    -

    Release Notes 4.0

    +
      +
    • 4.1.2 - Bug fix for GH-461 singleton scoped registrations to a child container
    • +
    • 4.1.1 - Bug fix for "AlwaysUnique" lifecycle within enumerable, inline dependencies
    • +
    +

    Release Notes 4.0.*

    4.0.1 was strictly a bug fix release.

    Release Notes 4.0

    4.0 is a medium sized release that largely builds on the existing 3.0 architecture with significant improvements to conventional @@ -192,25 +206,25 @@

    Release Notes 3.0

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -244,7 +258,7 @@

    Release Notes 3.0

    -}); +}); diff --git a/resolving/get-a-service-by-plugin-type-and-name/index.html b/resolving/get-a-service-by-plugin-type-and-name/index.html index 36479fa..a3cbd18 100644 --- a/resolving/get-a-service-by-plugin-type-and-name/index.html +++ b/resolving/get-a-service-by-plugin-type-and-name/index.html @@ -1,100 +1,98 @@ - + - StructureMap - Get a Service by Plugin Type and Name - - - - - - - - - + StructureMap - Get a Service by Plugin Type and Name + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Get all Services by Plugin Type

    -

    Previous

    Get a Service by PluginType

    - - -
    - - -
    -

    Get a Service by Plugin Type and Name Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Get a Service by Plugin Type and Name Edit on GitHub

    + +
    + +
    +

    You can also request a named configuration for a given PluginType by using the overloads of IContainer.GetInstance() that take in a name like this:

    
    -        [Test]
    +        [Fact]
             public void get_a_named_instance()
             {
                 var container = new Container(x =>
    @@ -110,33 +108,33 @@ 

    Get a Service by Plugin Type and Name Get a Service by PluginType + + + -

    -
    -
    +
    +
    +
    @@ -170,7 +168,7 @@

    Get a Service by Plugin Type and Name - + - StructureMap - Get a Service by PluginType - - - - - - - - - + StructureMap - Get a Service by PluginType + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Get a Service by Plugin Type and Name

    -

    Previous

    Resolving Services

    - - -
    - - -
    -

    Get a Service by PluginType Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Get a Service by PluginType Edit on GitHub

    + +
    + +
    +

    Requesting the default configured object of a plugin type is done through the IContainer.GetInstance() method shown below:

    
    -        [Test]
    +        [Fact]
             public void get_the_default_instance()
             {
                 var container = new Container(x => { x.For<IWidget>().Use<AWidget>(); });
    @@ -104,32 +102,32 @@ 

    Get a Service by PluginType Resolving Services + + + -

    -
    -
    +
    +
    +
    @@ -163,7 +161,7 @@

    Get a Service by PluginType - + - StructureMap - Get all Services by Plugin Type - - - - - - - - - + StructureMap - Get all Services by Plugin Type + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Try Getting an Optional Service by Plugin Type

    -

    Previous

    Get a Service by Plugin Type and Name

    - - -
    - - -
    -

    Get all Services by Plugin Type Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Get all Services by Plugin Type Edit on GitHub

    + +
    + +
    +

    Please see Working with Enumerable Types for a lot more information about what's going on behind the scenes.

    Once in a while you might want to get an enumerable of all the configured objects for a PluginType. That's done with the GetAllInstances() method shown below:

    
    -        [Test]
    +        [Fact]
             public void get_all_instances()
             {
                 var container = new Container(x =>
    @@ -108,39 +106,39 @@ 

    Get all Services by Plugin Type GetAllInstances() respects the order in which the actual instances are configured in the Container. Be warned that some other IoC tools make different assuptions if you are coming from a different tool.

    -
    +
    -
    +
    -
    -
    -
    -
    +
    +

    +

    @@ -174,7 +172,7 @@

    Get all Services by Plugin Type - + - StructureMap - Resolving Services - - - - - - - - - + StructureMap - Resolving Services + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Get a Service by PluginType

    -

    Previous

    Registration

    - - -
    - - -
    -

    Resolving Services Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Resolving Services Edit on GitHub

    + +
    + +
    +

    This will be the easy part of interacting with StructureMap. During application execution, you will need to resolve the services you previously registered in the container. When you ask StructureMap to resolve a service, StructureMap either creates a new object instance or finds the previously built object for the correct Object Lifecycles.

    While in many systems you will probably only resolve the default service of a type or a named instance of a service, there are far more ways to resolve services exposed by StructureMap. The IContainer interface acts as a Service Locator to build and resolve configured services on demand.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -148,7 +146,7 @@

    Resolving Services - + - StructureMap - Passing Arguments at Runtime - - - - - - - - - + StructureMap - Passing Arguments at Runtime + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Auto Resolving Concrete Types

    -

    Previous

    Try Geting an Optional Service by Plugin Type and Name

    - - -
    - - -
    -

    Passing Arguments at Runtime Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Passing Arguments at Runtime Edit on GitHub

    + +
    + +
    +

    Most of the time you will be using StructureMap to build objects based on pre-canned configuration established upfront, but StructureMap also has the capability to supply dependencies by type or named parameters (if you know the name of constructor arguments or setter property names) to the Container at runtime using the IContainer.With() methods.

    @@ -137,7 +135,7 @@

    Passing Arguments at Runtime - [Test] + [Fact] public void supply_named_arguments() { var container = new Container(x => { x.For<IWidget>().Use<ColorWidget>().Ctor<string>().Is("Red"); }); @@ -215,25 +213,25 @@

    Using the ExplicitArguments object

    -

    +
    -
    +
    -
    -
    -
    -
    +
    +
    + @@ -267,7 +265,7 @@

    Using the ExplicitArguments object

    -}); +}); diff --git a/resolving/requesting-a-concrete-type/index.html b/resolving/requesting-a-concrete-type/index.html index bbb71a8..3c9cf66 100644 --- a/resolving/requesting-a-concrete-type/index.html +++ b/resolving/requesting-a-concrete-type/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Auto Resolving Concrete Types - - - - - - - - - + StructureMap - Auto Resolving Concrete Types + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    The Container

    -

    Previous

    Passing Arguments at Runtime

    - - -
    - - -
    -

    Auto Resolving Concrete Types Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Auto Resolving Concrete Types Edit on GitHub

    + +
    + +
    +

    StructureMap allows you to resolve instances of concrete classes without configuring that concrete type with a few provisos:

    -
    -
    +
    +
    +
    @@ -203,7 +201,7 @@

    Auto Resolving Concrete Types - + - StructureMap - Try Geting an Optional Service by Plugin Type and Name - - - - - - - - - + StructureMap - Try Geting an Optional Service by Plugin Type and Name + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Passing Arguments at Runtime

    -

    Previous

    Try Getting an Optional Service by Plugin Type

    - - -
    - - -
    -

    Try Geting an Optional Service by Plugin Type and Name Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Try Geting an Optional Service by Plugin Type and Name Edit on GitHub

    + +
    + +
    +

    Just use the IContainer.TryGetInstance<T>(name) or IContainer.TryGetInstance(Type pluginType, string name) method as shown below:

    
    -        [Test]
    +        [Fact]
             public void TryGetInstanceViaNameAndGeneric_ReturnsInstance_WhenTypeFound()
             {
                 addColorInstance("Red");
    @@ -103,30 +101,31 @@ 

    Try Geting an Optional Service by Plugin Type and Name Try Getting an Optional Service by Plugin Type + + + -

    -
    -
    +
    +
    +
    @@ -160,7 +159,7 @@

    Try Geting an Optional Service by Plugin Type and Name - + - StructureMap - Try Getting an Optional Service by Plugin Type - - - - - - - - - + StructureMap - Try Getting an Optional Service by Plugin Type + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - - - - -
    -

    Try Getting an Optional Service by Plugin Type Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + + +
    @@ -264,7 +262,7 @@

    Optional Generic Types

    -}); +}); diff --git a/roadmap/index.html b/roadmap/index.html index cd716ec..80060eb 100644 --- a/roadmap/index.html +++ b/roadmap/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Roadmap - - - - - - - - - + StructureMap - Roadmap + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    A Gentle Quickstart

    -

    Previous

    Documentation

    - - -
    - - -
    -

    Roadmap Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Roadmap Edit on GitHub

    + +
    + +
    +

    StructureMap 3.0 released in early 2014 marked a huge change in the StructureMap internals and public API's. The 4.0 release was a much smaller release that primarily improved type scanning, diagnostics, and performance. The only breaking changes from 3 to 4 were in custom type scanning conventions, the removal of ObjectFactory, and @@ -98,32 +96,31 @@

    Roadmap StructureMap's GitHub page.

    Ongoing and upcoming work

      -
    1. The StructureMap codebase is going to finally move to xUnit.Net before doing any major new work.
    2. -
    3. A new package called StructureMap.DynamicInterception for adding support for AOP with Castle.Core dynamic proxies to StructureMap
    4. -
    5. The StructureMap.AutoFactory library is being rewritten based on Castle Dynamic Proxy to add more robust capabilities similar to what Windsor has
    6. -
    7. The StructureMap.DNX package for DNX integration (an early version is already available on Nuget.org)
    8. +
    9. StructureMap.DynamicInterception
    10. +
    11. StructureMap.AutoFactory
    12. +
    13. Auto Mocking updates and modernization
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    +
    @@ -157,7 +154,7 @@

    Ongoing and upcoming work

    -}); +}); diff --git a/setter-injection/index.html b/setter-injection/index.html index 193d28b..950aff6 100644 --- a/setter-injection/index.html +++ b/setter-injection/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Setter Injection - - - - - - - - - + StructureMap - Setter Injection + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Registration

    -

    Previous

    Software Design Concepts

    - - -
    - - -
    -

    Setter Injection Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Setter Injection Edit on GitHub

    + +
    + +
    + @@ -184,8 +182,7 @@

    Setter Injection Policies

    public IService Service { get; set; } } - - [Test] + [Fact] public void specify_setter_policy_and_construct_an_object() { var theService = new ColorService("red"); @@ -208,6 +205,7 @@

    Setter Injection Policies

    target.Service.ShouldBeTheSameAs(theService); target.Gateway.ShouldBeOfType<DefaultGateway>(); } +

    All calls to Registry.Policies.SetAllProperties() are additive, meaning you can use as many criteria as possible for setter injection.

    Filling Setter's of an Object

    @@ -220,10 +218,9 @@

    Filling Setter's of an Object

    public IService Service { get; set; } } - [Test] + [Fact] public void create_a_setter_rule_and_see_it_applied_in_BuildUp() { - var theGateway = new DefaultGateway(); var container = new Container(x => { @@ -237,29 +234,30 @@

    Filling Setter's of an Object

    target.Gateway.ShouldBeTheSameAs(theGateway); target.Service.ShouldBeNull(); } +

    The normal rules for what setters should be filled as described above apply to BuildUp().

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    +
    @@ -293,7 +291,7 @@

    Filling Setter's of an Object

    -}); +}); diff --git a/software-design-concepts/index.html b/software-design-concepts/index.html index 1a37410..b96eaa3 100644 --- a/software-design-concepts/index.html +++ b/software-design-concepts/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Software Design Concepts - - - - - - - - - + StructureMap - Software Design Concepts + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Setter Injection

    -

    Previous

    Features

    - - -
    - - -
    -

    Software Design Concepts Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Software Design Concepts Edit on GitHub

    + +
    + +
    +

    Inversion of Control

    Years ago I consulted for a company that had developed a successful software engine for pricing and analyzing potential energy trades. The next step for them was to adapt their pricing engine so that it could be embedded in other software packages or even a simple spreadsheet so that analysts could quickly try out "what if" scenarios before making any kind of deal. The immediate problem this firm had was that their pricing engine was archtected such that the pricing engine business logic directly invoked their proprietary database schema and configuration files. The strategic pricing engine logic was effectively useless without all the rest of their system, so forget embedding the logic into spreadsheet logic.

    @@ -114,6 +112,7 @@

    Dependency Injection

    // Setter Injection public IDatabase Database { get; set; } } +

    Service Locator

    StructureMap also fills the role of a service locator. In this usage, your code would directly access StructureMap's Container class to build or resolve services upon demand like this sample:

    @@ -128,29 +127,30 @@

    Service Locator

    _database = container.GetInstance<IDatabase>(); } } +

    Since IoC tools like StructureMap have come onto the software scene, many developers have very badly overused the service locator pattern and many other developers have become very vocal in their distaste for service location. The StructureMap team simply recommends that you favor Dependency Injection wherever possible, but that some service location in your system where you may need more advanced building options or lazy resolution of services is probably just fine.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    +

    @@ -184,7 +184,7 @@

    Service Locator

    -}); +}); diff --git a/the-container/auto-wiring/index.html b/the-container/auto-wiring/index.html index 0216c12..8e3459c 100644 --- a/the-container/auto-wiring/index.html +++ b/the-container/auto-wiring/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Auto Wiring - - - - - - - - - + StructureMap - Auto Wiring + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Building Objects with Lambdas

    -

    Previous

    The Container

    - - -
    - - -
    -

    Auto Wiring Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Auto Wiring Edit on GitHub

    + +
    + +
    +

    The best way to use an IoC container is to allow "Auto Wiring" to do most of the work for you. IoC Containers like StructureMap are an infrastructure concern, and as such, should be isolated from as much of your code as possible. Before examining Auto Wiring in depth, let's look at a common anti pattern of IoC usage:

    
    @@ -161,25 +159,25 @@ 

    Auto Wiring Working with Primitive Types for more information on how StructureMap deals with primitive types like numbers, strings, enums, and dates in auto-wiring.

    -

    +
    -
    +
    - -
    -
    -
    +
    +
    +

    @@ -213,7 +211,7 @@

    Auto Wiring - + - StructureMap - StructureMap and IDisposable - - - - - - - - - + StructureMap - StructureMap and IDisposable + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Working with Primitive Types

    -

    Previous

    Lazy Resolution

    - - -
    - - -
    -

    StructureMap and IDisposable Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    StructureMap and IDisposable Edit on GitHub

    + +
    + +
    +

    Singletons

    This one is easy, any object marked as the Singleton lifecycle that implements IDisposable is disposed when the root container is disposed:

    
    -        [Test]
    +        [Fact]
             public void singletons_are_disposed_when_the_container_is_disposed()
             {
                 var container = new Container(_ =>
    @@ -119,6 +117,7 @@ 

    Singletons

    // the SingletonThing scoped object should be disposed singleton.WasDisposed.ShouldBeTrue(); } +

    Ejecting a singleton-scoped object will also force it to be disposed. See Using the Container Model for more information on how to eject singletons from a running Container.

    @@ -126,7 +125,7 @@

    Nested Containers

    As discussed in Nested Containers (Per Request/Transaction), any transient, AlwaysUnique (as of 4.0), or container-scoped object that implements IDisposable and is created by a nested container will be disposed as the nested container is disposed:

    
    -        [Test]
    +        [Fact]
             public void nested_container_disposal()
             {
                 var container = new Container(_ =>
    @@ -155,7 +154,6 @@ 

    Nested Containers

    nestedGreen = nested.GetInstance<IColor>() .ShouldBeOfType<Green>(); - nestedBlue = nested.GetInstance<Blue>(); nestedPurple = nested.GetInstance<Purple>(); @@ -170,7 +168,6 @@

    Nested Containers

    // are disposed nestedPurple.WasDisposed.ShouldBeTrue(); - // NOT disposed because it's owned by // the parent container singleton.WasDisposed.ShouldBeFalse(); @@ -185,7 +182,7 @@

    Transients

    an explicit Release(object) mode as other IoC containers behave would do more harm than good (memory leaks from forgetting to call Release(), more work on the user).

    That all being said, in order to comply with the new ASP.Net vNext compliance behavior, StructureMap 4.0 introduces a new opt-in transient tracking mode with the prerequisite Release(object) method:

    
    -        [Test]
    +        [Fact]
             public void release_transient_created_by_root_container()
             {
                 var container = new Container(_ => _.TransientTracking = TransientTracking.ExplicitReleaseMode);
    @@ -197,22 +194,21 @@ 

    Transients

    transient1.WasDisposed.ShouldBeFalse(); transient2.WasDisposed.ShouldBeFalse(); - + // release ONLY transient2 container.Release(transient2); - transient1.WasDisposed.ShouldBeFalse(); transient2.WasDisposed.ShouldBeTrue(); - // transient2 should no longer be + // transient2 should no longer be // tracked by the container container.TransientTracking.Tracked .Single() .ShouldBeTheSameAs(transient1); } - [Test] + [Fact] public void disposing_the_container_disposes_tracked_transients() { var container = new Container(_ => _.TransientTracking = TransientTracking.ExplicitReleaseMode); @@ -228,30 +224,31 @@

    Transients

    transient1.WasDisposed.ShouldBeTrue(); transient2.WasDisposed.ShouldBeTrue(); } +

    As of right now, StructureMap will only track the top level object requested from a Container and not all the other IDisposable objects that may have been created as part of the main object graph.

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -285,7 +282,7 @@

    Transients

    -}); +}); diff --git a/the-container/forwarding-requests-for-a-type-to-another-type/index.html b/the-container/forwarding-requests-for-a-type-to-another-type/index.html index ab1f710..8fd83c3 100644 --- a/the-container/forwarding-requests-for-a-type-to-another-type/index.html +++ b/the-container/forwarding-requests-for-a-type-to-another-type/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Registering a Single Instance Against Multiple PluginType's - - - - - - - - - + StructureMap - Registering a Single Instance Against Multiple PluginType's + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Profiles and Child Containers

    -

    Previous

    Working with the IContext at Build Time

    - - -
    - - -
    -

    Registering a Single Instance Against Multiple PluginType's Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Registering a Single Instance Against Multiple PluginType's Edit on GitHub

    + +
    + +
    -
    -
    +
    +
    +
    @@ -202,7 +202,7 @@

    Registering a Single Instance Against Multiple PluginType's - + - StructureMap - Handling Missing Named Instances - - - - - - - - - + StructureMap - Handling Missing Named Instances + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Lazy Resolution

    -

    Previous

    Working with Enumerable Types

    - - -
    - - -
    -

    Handling Missing Named Instances Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Handling Missing Named Instances Edit on GitHub

    + +
    + +
    +

    Let's say that something asks StructureMap to resolve a named instance of a type that StructureMap does not know about. What if instead of throwing the exception for an unknown named service, StructureMap could be taught to create a new registration for that type for the name @@ -117,7 +115,7 @@

    Handling Missing Named Instances - [Test] + [Fact] public void configure_and_use_missing_instance() { var container = new Container(x => @@ -140,7 +138,7 @@

    Handling Missing Named Instances - [Test] + [Fact] public void does_not_override_explicit_registrations() { var container = new Container(x => @@ -160,14 +158,14 @@

    Handling Missing Named Instances - [Test] + [Fact] public void configure_and_use_missing_instance_by_generic_registration() { var instance = new LambdaInstance<ColorRule>(c => new ColorRule(c.RequestedName)); var container = new Container(x => { - x.For(typeof (Rule)) + x.For(typeof(Rule)) .MissingNamedInstanceIs(instance); }); @@ -204,7 +202,7 @@

    Multi-Tenancy

    then we could allow client specific rules while still allowing the container to fall through to the default rules for clients that don't need customized rules:

    
    -        [Test]
    +        [Fact]
             public void use_customer_overrides()
             {
                 var container = new Container(_ =>
    @@ -219,7 +217,7 @@ 

    Multi-Tenancy

    container.GetInstance<Rule>("client1").ShouldBeOfType<Client1Rule>(); container.GetInstance<Rule>("client2").ShouldBeOfType<Client2Rule>(); - // Client3 has no explicit registration, so falls through to + // Client3 has no explicit registration, so falls through to // DefaultRule container.GetInstance<Rule>("client3").ShouldBeOfType<DefaultRule>(); } @@ -248,7 +246,7 @@

    Multi-Tenancy

    } } - [Test] + [Fact] public void register_by_looking_up_data() { var container = new Container(_ => @@ -267,25 +265,25 @@

    Multi-Tenancy

    -

    +
    -
    +
    -
    -
    -
    -
    +
    +
    +

    @@ -319,7 +317,7 @@

    Multi-Tenancy

    -}); +}); diff --git a/the-container/index.html b/the-container/index.html index 1718950..821d3ca 100644 --- a/the-container/index.html +++ b/the-container/index.html @@ -1,121 +1,119 @@ - + - StructureMap - The Container - - - - - - - - - + StructureMap - The Container + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Auto Wiring

    -

    Previous

    Resolving Services

    - - -
    - - -
    -

    The Container Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + + -
    +
    - -
    -
    -
    +
    +
    + @@ -149,7 +147,7 @@

    The Container - + - StructureMap - Building Objects with Lambdas - - - - - - - - - + StructureMap - Building Objects with Lambdas + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Working with the IContext at Build Time

    -

    Previous

    Auto Wiring

    - - -
    - - -
    -

    Building Objects with Lambdas Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Building Objects with Lambdas Edit on GitHub

    + +
    + +
    +

    Instead of allowing StructureMap to build objects directly, you can give a StructureMap Container a Lambda function that can be called to create an object at resolution time.

    Using NHibernate's ISession as an example of an object that typically has to be built by using an ISessionFactory object:

    @@ -137,25 +135,25 @@

    Building Objects with Lambdas Working with the IContext at Build Time for more information.

    -

    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -189,7 +187,7 @@

    Building Objects with Lambdas - + - StructureMap - Lazy Resolution - - - - - - - - - + StructureMap - Lazy Resolution + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    StructureMap and IDisposable

    -

    Previous

    Handling Missing Named Instances

    - - -
    - - -
    -

    Lazy Resolution Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Lazy Resolution Edit on GitHub

    + +
    + +
    +

    StructureMap has some built in functionality for "lazy" resolved dependencies, so that instead of your application service taking a direct dependency on IExpensiveToBuildService that might not be necessary, you could instead have StructureMap fulfil a dependency on Lazy<IExpensiveToBuildService> or Func<IExpensiveToBuildService> @@ -119,7 +117,7 @@

    Lazy<T>

    } } - [Test] + [Fact] public void lazy_resolution_in_action() { var container = new Container(_ => @@ -130,11 +128,12 @@

    Lazy<T>

    container.GetInstance<WidgetLazyUser>() .Widget.ShouldBeOfType<AWidget>(); } +

    Func<T>

    Likewise, you can also declare a dependency on Func<T> with very similar mechanics:

    
    -        [Test]
    +        [Fact]
             public void build_a_func_that_returns_a_singleton()
             {
                 var container = new Container(x =>
    @@ -153,13 +152,14 @@ 

    Func<T>

    w1.ShouldBeTheSameAs(w3); w2.ShouldBeTheSameAs(w3); } +

    This functionality predates the introduction of the Lazy type to .Net

    Func<string, T>

    Finally, you can also declare a dependency on Func<string, T> that will allow you to lazily resolve a dependency of T by name:

    
    -        [Test]
    +        [Fact]
             public void build_a_func_by_string()
             {
                 var container = new Container(x =>
    @@ -172,6 +172,7 @@ 

    Func<string, T>

    var func = container.GetInstance<Func<string, IWidget>>(); func("green").ShouldBeOfType<ColorWidget>().Color.ShouldBe("green"); } +

    Bi-relational Dependency Workaround

    StructureMap does not directly support bi-directional dependency relationships -- but will happily tell you in an exception when @@ -181,7 +182,7 @@

    Bi-relational Dependency Workaround

    
     
             [Singleton]
    -        public class Thing1 
    +        public class Thing1
             {
                 private readonly Lazy<Thing2> _thing2;
     
    @@ -197,7 +198,7 @@ 

    Bi-relational Dependency Workaround

    } [Singleton] - public class Thing2 + public class Thing2 { public Thing1 Thing1 { get; set; } @@ -207,7 +208,7 @@

    Bi-relational Dependency Workaround

    } } - [Test] + [Fact] public void use_lazy_as_workaround_for_bi_directional_dependency() { var container = new Container(); @@ -217,28 +218,29 @@

    Bi-relational Dependency Workaround

    thing1.Thing2.ShouldBeSameAs(thing2); thing2.Thing1.ShouldBeSameAs(thing1); } +
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -272,7 +274,7 @@

    Bi-relational Dependency Workaround

    -}); +}); diff --git a/the-container/nested-containers/index.html b/the-container/nested-containers/index.html index 1b0c5c8..2cb0efd 100644 --- a/the-container/nested-containers/index.html +++ b/the-container/nested-containers/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Nested Containers (Per Request/Transaction) - - - - - - - - - + StructureMap - Nested Containers (Per Request/Transaction) + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Working with Enumerable Types

    -

    Previous

    Profiles and Child Containers

    - - -
    - - -
    -

    Nested Containers (Per Request/Transaction) Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Nested Containers (Per Request/Transaction) Edit on GitHub

    + +
    + +
    +

    Nested Container's are a powerful feature in StructureMap for service resolution and clean object disposal in the @@ -106,7 +104,7 @@

    History

    resolution of the message handler. The result was what is now the nested container feature of StructureMap.

    Why Nested Containers over HttpContext or ThreadLocal Scoping?

    -

    Why not just use HttpContext based lifecycles like we've always done in the past? Because HttpContext is not supported by the any +

    Why not just use HttpContext based lifecycles like we've always done in the past? Because HttpContext is not supported by any type of OWIN web host and will not be a part of ASP.Net vNext. Using a Nested Container per HTTP request is a better, lighterweight way to scope services to an HTTP request without coupling your code to what will soon be legacy ASP.Net runtime code.

    Who uses it?

    @@ -134,7 +132,7 @@

    Creation

    } } - [Test] + [Fact] public void creating_a_nested_container() { // From an IContainer object @@ -151,14 +149,14 @@

    Creation

    Lifecycle Rules

    -

    While StructureMap supports several object instance lifecycles out of the boxy, in idiomatic usage of StructureMap the only common lifecyles are:

    +

    While StructureMap supports several object instance lifecycles out of the box, in idiomatic usage of StructureMap the only common lifecyles are:

    1. Transient - The default lifecycle. A new object is created for a configured Instance on each request to the container
    2. Singleton - One instance is constructed and used over the entire Container lifetime

    In the context of a Nested Container however, the Transient scoping now applies to the Nested Container itself:

    
    -        [Test]
    +        [Fact]
             public void nested_container_behavior_of_transients()
             {
                 // "Transient" is the default lifecycle
    @@ -185,9 +183,9 @@ 

    Lifecycle Rules

    }
    -

    Instance's scoped to anything but Transient or AlwaysUnique are resolved as normal, but through the parent container:

    +

    Instances scoped to anything but Transient or AlwaysUnique are resolved as normal, but through the parent container:

    
    -        [Test]
    +        [Fact]
             public void nested_container_usage_of_singletons()
             {
                 var container = new Container(_ => { _.ForSingletonOf<IColorCache>().Use<ColorCache>(); });
    @@ -206,14 +204,14 @@ 

    Lifecycle Rules

    See <linkto:object-lifecycle]> for more information on supported object lifecycles.

    Overriding Services from the Parent

    A nested container is a new Container object that still retains access to the parent container that created it so that it can -efficiently share registrations, policies, and cached build plan's. You can, however, register services into the nested container that override the parent container.

    +efficiently share registrations, policies, and cached build plans. You can, however, register services into the nested container that override the parent container.

    The FubuMVC web framework uses a nested container per HTTP request. During an HTTP request, FubuMVC injects services for the current HTTP request and response to a nested container before creating the actual services that will handle the request. The FubuMVC mechanics are conceptually similar to this code sample:

    
    -        [Test]
    +        [Fact]
             public void overriding_services_in_a_nested_container()
             {
                 var container = new Container(_ =>
    @@ -278,7 +276,7 @@ 

    Lazy Resolution

    } } - [Test] + [Fact] public void service_location_and_container_resolution_inside_nested_containers() { var container = new Container(); @@ -290,7 +288,7 @@

    Lazy Resolution

    // The injected IContainer is the nested container holder.Container.ShouldBeTheSameAs(nested); - // Func<T> and Lazy<T> values will be built by + // Func<T> and Lazy<T> values will be built by // the nested container w/ the nested container // scoping var nestedFoo = nested.GetInstance<Foo>(); @@ -313,7 +311,7 @@

    Disposing Services

    nested container that implement the IDisposable interface. That behavior is demonstrated below:

    
    -        [Test]
    +        [Fact]
             public void nested_container_disposal()
             {
                 var container = new Container(_ =>
    @@ -342,7 +340,6 @@ 

    Disposing Services

    nestedGreen = nested.GetInstance<IColor>() .ShouldBeOfType<Green>(); - nestedBlue = nested.GetInstance<Blue>(); nestedPurple = nested.GetInstance<Purple>(); @@ -357,7 +354,6 @@

    Disposing Services

    // are disposed nestedPurple.WasDisposed.ShouldBeTrue(); - // NOT disposed because it's owned by // the parent container singleton.WasDisposed.ShouldBeFalse(); @@ -374,7 +370,7 @@

    Disposing Services

    { } - public class Purple : Blue { } + public class Purple : Blue { } public class Blue : IColor, IDisposable { @@ -413,25 +409,25 @@

    Disposing Services

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -465,7 +461,7 @@

    Disposing Services

    -}); +}); diff --git a/the-container/primitives/index.html b/the-container/primitives/index.html index 8c72a97..1e4e1e5 100644 --- a/the-container/primitives/index.html +++ b/the-container/primitives/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Working with Primitive Types - - - - - - - - - + StructureMap - Working with Primitive Types + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Object Lifecycles

    -

    Previous

    StructureMap and IDisposable

    - - -
    - - -
    -

    Working with Primitive Types Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Working with Primitive Types Edit on GitHub

    + +
    + +
    +

    StructureMap treats simple types like strings, numbers of any kind, enumerations, and dates as primitive types that are completely exempt from auto wiring -- meaning that any constructor or setter dependencies on these types must be supplied as inline dependencies.

    @@ -106,7 +104,7 @@

    Working with Primitive Types

    Part of the exception message thrown in the unit test shown above is the erroneous build plan showing you that the name parameter has to be defined:

    @@ -126,7 +125,7 @@

    Working with Primitive Types - [Test] + [Fact] public void can_build_with_explicit_argument() { var container = new Container(_ => @@ -138,6 +137,7 @@

    Working with Primitive Types Construction Policies for an example of using a constructor policy to set a dependency on a "connectionString" argument in a conventional way.

    @@ -158,7 +158,7 @@

    Default Values

    public string Name { get; set; } } - [Test] + [Fact] public void uses_the_default_value_if_one_exists() { var container = new Container(); @@ -169,7 +169,7 @@

    Default Values

    .Name.ShouldBe("Jim Croce"); } - [Test] + [Fact] public void uses_the_default_value_if_one_exists_2() { var container = new Container(_ => @@ -183,7 +183,7 @@

    Default Values

    .Name.ShouldBe("Jim Croce"); } - [Test] + [Fact] public void use_explicit_dependency_if_one_exists() { var container = new Container(_ => @@ -195,28 +195,29 @@

    Default Values

    container.GetInstance<GuyWithName>() .Name.ShouldBe("Eric Clapton"); } +
    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -250,7 +251,7 @@

    Default Values

    -}); +}); diff --git a/the-container/profiles-and-child-containers/index.html b/the-container/profiles-and-child-containers/index.html index eaca57d..ed131fe 100644 --- a/the-container/profiles-and-child-containers/index.html +++ b/the-container/profiles-and-child-containers/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Profiles and Child Containers - - - - - - - - - + StructureMap - Profiles and Child Containers + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - - - - -
    -

    Profiles and Child Containers Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Profiles and Child Containers Edit on GitHub

    + +
    + +
    +

    The single best source for information about the particulars of child container behavior is to look through the acceptance tests for child containers and @@ -99,7 +97,7 @@

    Profiles and Child Containers - [Test] + [Fact] public void show_a_child_container_in_action() { var parent = new Container(_ => @@ -127,6 +125,7 @@

    Child Containers

    child.GetInstance<IWidget>() .ShouldBeOfType<AWidget>(); } +

    Child Container's are a mechanism to make a completely new Container that can override some of the parent Container's registrations but still fall back to the parent Container to fulfill any request that is not explicitly configured to the child container. The behavior of a child container @@ -145,7 +144,7 @@

    Profiles

    servers to production. While that usage is still valid, it is probably more common to use profiles to define overrides for how StructureMap should resolve services in different modes of the application (connected vs offline) or different types of system users.

    
    -        [Test]
    +        [Fact]
             public void Add_default_instance_with_concrete_type()
             {
                 IContainer container = new Container(registry =>
    @@ -162,12 +161,13 @@ 

    Profiles

    profile.GetInstance<IWidget>().ShouldBeOfType<AWidget>(); profile.GetInstance<Rule>().ShouldBeOfType<DefaultRule>(); } +

    Child Containers and Singletons

    If you register a new Instance directly to a child container, that registration is really scoped as a singleton within the usage of that particular child container:

    
    -        [Test]
    +        [Fact]
             public void singletons_to_child_container_are_isolated()
             {
                 var parentContainer = new Container(_ =>
    @@ -195,13 +195,14 @@ 

    Child Containers and Singletons

    // but, child1 and child2 both have a different IRoot child1.GetInstance<IRoot>() - .ShouldNotBeTheSameAs(child2); + .ShouldNotBeTheSameAs(child2.GetInstance<IRoot>()); } +

    Creating a Nested Container from a Child Container

    It is perfectly valid to create a nested container from a child container for short-lived requests or transactions:

    
    -        [Test]
    +        [Fact]
             public void nested_container_from_child()
             {
                 var parent = new Container(_ =>
    @@ -224,6 +225,7 @@ 

    Creating a Nested Container from a Child Container

    .ShouldBeOfType<ChildSpecialService>(); } } +

    Example: Child Containers in Automated Testing

    My shop has been somewhat successful in writing automated integration tests in a whitebox testing style @@ -241,7 +243,7 @@

    Example: Child Containers in Automated Testing

    public class StubbedService : IService { } - [Test] + [Fact] public void in_testing() { var container = new Container(_ => @@ -259,28 +261,29 @@

    Example: Child Containers in Automated Testing

    // Now, continue with the test resolving application // services through the new child container.... } +
    -

    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -314,7 +317,7 @@

    Example: Child Containers in Automated Testing

    -}); +}); diff --git a/the-container/working-with-enumerable-types/index.html b/the-container/working-with-enumerable-types/index.html index 2d0ed8c..0aa762e 100644 --- a/the-container/working-with-enumerable-types/index.html +++ b/the-container/working-with-enumerable-types/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Working with Enumerable Types - - - - - - - - - + StructureMap - Working with Enumerable Types + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.1.0

    -
    - - -

    Next

    Handling Missing Named Instances

    -

    Previous

    Nested Containers (Per Request/Transaction)

    - - -
    - - -
    -

    Working with Enumerable Types Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + + -
    +
    +
    + @@ -248,7 +247,7 @@

    Sample Usage: Validation Rules

    -}); +}); diff --git a/the-container/working-with-the-icontext-at-build-time/index.html b/the-container/working-with-the-icontext-at-build-time/index.html index 1302d16..46b5320 100644 --- a/the-container/working-with-the-icontext-at-build-time/index.html +++ b/the-container/working-with-the-icontext-at-build-time/index.html @@ -1,96 +1,94 @@ - + - StructureMap - Working with the IContext at Build Time - - - - - - - - - + StructureMap - Working with the IContext at Build Time + + + + + + + + + + + - + - + Fork me on GitHub - + - -
    - -
    - - -
    -
    - - - - - -
    -

    Working with the IContext at Build Time Edit on GitHub

    - -
    - -
    - + + +
    + + +
    + +
    + + +
    +
    + + + + + +
    +

    Working with the IContext at Build Time Edit on GitHub

    + +
    + +
    +

    The IContext usage shown in this topic is certainly not going away in future versions of StructureMap, but if at all possible, the StructureMap team strongly recommends using Construction Policies to accomplish customized object building instead of relying @@ -236,11 +234,12 @@

    Example 1: Contextual Logging

    return new Logger(type); } } +

    Now, say you would want to have the proper Logger injected into every object that StructureMap creates that depends on Logger matching the concrete type of the object being created. That registration is shown below in a unit test from StructureMap's codebase:

    
    -        [Test]
    +        [Fact]
             public void can_happily_use_the_parent_type()
             {
                 var container = new Container(x =>
    @@ -251,10 +250,11 @@ 

    Example 1: Contextual Logging

    }); var top = container.GetInstance<LoggedClass1>(); - top.Logger.ParentType.ShouldBe(typeof (LoggedClass1)); - top.Child.Logger.ParentType.ShouldBe(typeof (LoggedClass2)); - top.Child.Child.Logger.ParentType.ShouldBe(typeof (LoggedClass3)); + top.Logger.ParentType.ShouldBe(typeof(LoggedClass1)); + top.Child.Logger.ParentType.ShouldBe(typeof(LoggedClass2)); + top.Child.Child.Logger.ParentType.ShouldBe(typeof(LoggedClass3)); } +

    Just for fun, here's the equivalent with the new construction policies from 4.0:

    
    @@ -269,7 +269,7 @@ 

    Example 1: Contextual Logging

    } } - [Test] + [Fact] public void use_logger_convention() { var container = new Container(_ => @@ -282,6 +282,7 @@

    Example 1: Contextual Logging

    top.Child.Logger.ParentType.ShouldBe(typeof(LoggedClass2)); top.Child.Child.Logger.ParentType.ShouldBe(typeof(LoggedClass3)); } +

    The LoggerConvention way of accomplishing the logging integration is technically more code and possibly harder to understand, but it's significantly more efficient at runtime because the decision about which Logger to use is only done once upfront. @@ -323,25 +324,25 @@

    Example 2: NHibernate Integration

    -
    +
    -
    +
    - -
    -
    -
    +
    +
    + @@ -375,7 +376,7 @@

    Example 2: NHibernate Integration

    -}); +}); From 6c93dfaccee25cfec64120583aa01f6355ad0421 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 3 Jan 2017 09:46:43 -0600 Subject: [PATCH 39/55] Documentation Update for 4.4.2 From da597fc6cc4d7c3424b88a37781503df137e2b88 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 3 Jan 2017 09:51:13 -0600 Subject: [PATCH 40/55] Documentation Update for 4.4.2 From acc9e29090885c0df37eb61166cb31397824cd06 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 3 Jan 2017 09:53:19 -0600 Subject: [PATCH 41/55] Documentation Update for 4.4.2 From bc6053fe035a5194bd7fd7f0b216d739033e53c4 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 3 Jan 2017 09:55:10 -0600 Subject: [PATCH 42/55] Documentation Update for 4.4.2 --- architecture/index.html | 156 ------ autofactory/index.html | 150 ++++++ best-practices/index.html | 87 ++-- diagnostics/build-plans/index.html | 77 ++- diagnostics/environment-tests/index.html | 42 +- diagnostics/index.html | 13 +- diagnostics/type-scanning/index.html | 79 +-- .../using-the-container-model/index.html | 162 ++---- .../index.html | 64 ++- diagnostics/whatdoihave/index.html | 75 +-- documentation/index.html | 7 +- dynamic-interception/index.html | 150 ++++++ faq/index.html | 157 ------ features/index.html | 81 ++- generics/index.html | 436 ++--------------- get-structuremap/index.html | 41 +- glossary/index.html | 261 +++------- history/index.html | 29 +- instances/index.html | 28 +- integrations/index.html | 57 ++- interception-and-decorators/index.html | 440 ++++------------- interpreting-exceptions/index.html | 39 +- .../configuring-lifecycles/index.html | 90 +--- object-lifecycle/custom-lifecycles/index.html | 58 +-- object-lifecycle/index.html | 85 +--- .../supported-lifecycles/index.html | 462 +++--------------- quickstart/index.html | 140 ++---- registration/attributes/index.html | 154 +----- .../index.html | 443 ++++------------- .../index.html | 55 +-- registration/clear-or-replace/index.html | 37 +- registration/configured-instance/index.html | 241 +-------- .../configuring-the-raw-model/index.html | 157 ------ registration/constructor-selection/index.html | 290 ++--------- registration/existing-objects/index.html | 17 +- registration/fallback-services/index.html | 103 +--- registration/index.html | 144 ++---- registration/inline-dependencies/index.html | 419 ++-------------- .../on-missing-family-policies/index.html | 247 ++-------- registration/policies/index.html | 281 +---------- registration/registry-dsl/index.html | 230 ++------- .../setter-injection-policies/index.html | 157 ------ release-notes/index.html | 224 ++++----- .../index.html | 35 +- .../get-a-service-by-plugintype/index.html | 28 +- .../index.html | 42 +- resolving/index.html | 13 +- .../passing-arguments-at-runtime/index.html | 159 ++---- .../requesting-a-concrete-type/index.html | 80 +-- .../index.html | 26 +- .../index.html | 152 ++---- roadmap/index.html | 29 +- setter-injection/index.html | 132 +---- software-design-concepts/index.html | 60 +-- the-container/auto-wiring/index.html | 106 ++-- the-container/buildup/index.html | 156 ------ the-container/disposing/index.html | 136 +----- .../index.html | 84 +--- .../index.html | 212 ++------ the-container/index.html | 15 +- the-container/lambdas/index.html | 35 +- the-container/lazy-resolution/index.html | 125 +---- the-container/nested-containers/index.html | 394 +++------------ the-container/primitives/index.html | 103 +--- .../profiles-and-child-containers/index.html | 225 ++------- .../structuremap-assumptions/index.html | 157 ------ .../working-with-enumerable-types/index.html | 140 ++---- .../working-with-generic-types/index.html | 157 ------ .../index.html | 279 ++--------- 69 files changed, 1935 insertions(+), 7810 deletions(-) delete mode 100644 architecture/index.html create mode 100644 autofactory/index.html create mode 100644 dynamic-interception/index.html delete mode 100644 faq/index.html delete mode 100644 registration/configuring-the-raw-model/index.html delete mode 100644 registration/setter-injection-policies/index.html delete mode 100644 the-container/buildup/index.html delete mode 100644 the-container/structuremap-assumptions/index.html delete mode 100644 the-container/working-with-generic-types/index.html diff --git a/architecture/index.html b/architecture/index.html deleted file mode 100644 index 758b204..0000000 --- a/architecture/index.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - StructureMap - Internals and Architecture - - - - - - - - - - - - - - - - - - - -Fork me on GitHub - - - -
    - -
    - - -
    -
    - - -
    -

    StructureMap 4.0.0

    -
    - - - -

    Next

    Best Practices

    -

    Previous

    Diagnostics

    - - -
    - - -
    -

    Internals and Architecture

    - -
    - -
    - -

    TODO(Write content!)

    - - -
    - -
    - - - -
    -
    -
    - - - - - - - - - - - - - - - - - - diff --git a/autofactory/index.html b/autofactory/index.html new file mode 100644 index 0000000..e584eef --- /dev/null +++ b/autofactory/index.html @@ -0,0 +1,150 @@ + + + + + + + + StructureMap - StructureMap.AutoFactory + + + + + + + + + + + + + + + + + + + + +Fork me on GitHub + + + +
    + +
    + + +
    +
    + + + + + +
    +

    StructureMap.AutoFactory Edit on GitHub

    + +
    + +
    + + +
    + +
    + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + diff --git a/best-practices/index.html b/best-practices/index.html index 6ebd4a9..b68501a 100644 --- a/best-practices/index.html +++ b/best-practices/index.html @@ -31,7 +31,7 @@