hammett 2003/09/27 16:58:29
Modified: avalon-net/cscontainer/AvalonContainerTest
AvalonContainerTest.csproj
DependencyHandlingTestCase.cs
avalon-net/cscontainer/AvalonContainerTest/Components
Vehicle.cs
avalon-net/cscontainer/Samples/bin/Samples
Samples.Components.dll
avalon-net/cscontainer/bin Apache.Avalon.Container.Test.dll
Apache.Avalon.Container.dll
Apache.Avalon.Framework.dll
avalon-net/csframework/AvalonFramework Attributes.cs
avalon-net/csframework/bin Apache.Avalon.Framework.Test.dll
Apache.Avalon.Framework.dll
Added: avalon-net/cscontainer/AvalonContainerTest/Components Bus.cs
Log:
DependencyAttribute must be Inherited=true. Added Unit tests to protected ourself
from this bug.
Revision Changes Path
1.2 +5 -0
avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/AvalonContainerTest.csproj
Index: AvalonContainerTest.csproj
===================================================================
RCS file:
/home/cvs/avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/AvalonContainerTest.csproj,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AvalonContainerTest.csproj 22 Sep 2003 23:49:23 -0000 1.1
+++ AvalonContainerTest.csproj 27 Sep 2003 23:58:29 -0000 1.2
@@ -134,6 +134,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "Components\Bus.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "Components\Calculator.cs"
SubType = "Code"
BuildAction = "Compile"
1.2 +37 -6
avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/DependencyHandlingTestCase.cs
Index: DependencyHandlingTestCase.cs
===================================================================
RCS file:
/home/cvs/avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/DependencyHandlingTestCase.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DependencyHandlingTestCase.cs 22 Sep 2003 23:49:23 -0000 1.1
+++ DependencyHandlingTestCase.cs 27 Sep 2003 23:58:29 -0000 1.2
@@ -61,19 +61,50 @@
[Test]
public void ShutDownOrderCheck()
{
- Assertion.AssertEquals(5, m_container.ShutDownOrder.Length);
+ Assertion.AssertEquals(6, m_container.ShutDownOrder.Length);
- Assertion.AssertEquals(typeof(IVehicle).FullName,
m_container.ShutDownOrder[0].Name);
- Assertion.AssertEquals(typeof(IEngine).FullName,
m_container.ShutDownOrder[1].Name);
+ Assertion.AssertEquals(typeof(IBus).FullName,
m_container.ShutDownOrder[0].Name);
+ Assertion.AssertEquals(typeof(IVehicle).FullName,
m_container.ShutDownOrder[1].Name);
+ Assertion.AssertEquals(typeof(IRadio).FullName,
m_container.ShutDownOrder[2].Name);
+ Assertion.AssertEquals(typeof(IEngine).FullName,
m_container.ShutDownOrder[3].Name);
}
[Test]
public void ComponentWithDependency()
{
- IVehicle vehicle = (IVehicle)
- m_container.LookupManager[ typeof(IVehicle).FullName ];
+ IVehicle vehicle = null;
+
+ try
+ {
+ vehicle = (IVehicle) m_container.LookupManager[
typeof(IVehicle).FullName ];
+ }
+ finally
+ {
+ if (vehicle != null)
+ {
+ m_container.LookupManager.Release(vehicle);
+ }
+ }
+ }
+
+ [Test]
+ public void ComponentWithInheritedDependency()
+ {
+ IBus bus = null;
+
+ try
+ {
+ bus = (IBus) m_container.LookupManager[
typeof(IBus).FullName ];
- m_container.LookupManager.Release(vehicle);
+ bus.Travel();
+ }
+ finally
+ {
+ if (bus != null)
+ {
+ m_container.LookupManager.Release(bus);
+ }
+ }
}
}
}
1.2 +1 -9
avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/Components/Vehicle.cs
Index: Vehicle.cs
===================================================================
RCS file:
/home/cvs/avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/Components/Vehicle.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Vehicle.cs 22 Sep 2003 23:49:23 -0000 1.1
+++ Vehicle.cs 27 Sep 2003 23:58:29 -0000 1.2
@@ -53,7 +53,7 @@
using Apache.Avalon.Framework;
/// <summary>
- /// Summary description for Vehicle.
+ /// Definitions for IVehicle service.
/// </summary>
public interface IVehicle
{
@@ -114,8 +114,6 @@
}
}
- #region ILookupEnabled Members
-
public void EnableLookups(ILookupManager manager)
{
Assertion.AssertNotNull(manager);
@@ -126,16 +124,12 @@
Assertion.Equals( typeof(IEngine), manager["Engine"].GetType()
);
Assertion.Equals( typeof(IRadio), manager["Radio"].GetType() );
}
-
- #endregion
}
[AvalonService( typeof(IEngine) )]
[AvalonComponent( "Engine", Lifestyle.Transient )]
public class Engine : IEngine
{
- #region IEngine Members
-
public void TurnOn()
{
}
@@ -143,8 +137,6 @@
public void TurnOff()
{
}
-
- #endregion
}
[AvalonService( typeof(IRadio) )]
1.1
avalon-sandbox/avalon-net/cscontainer/AvalonContainerTest/Components/Bus.cs
Index: Bus.cs
===================================================================
// ============================================================================
// The Apache Software License, Version 1.1
// ============================================================================
//
// Copyright (C) 2002-2003 The Apache Software Foundation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modifica-
// tion, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. The end-user documentation included with the redistribution, if any, must
// include the following acknowledgment: "This product includes software
// developed by the Apache Software Foundation (http://www.apache.org/)."
// Alternately, this acknowledgment may appear in the software itself, if
// and wherever such third-party acknowledgments normally appear.
//
// 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
// must not be used to endorse or promote products derived from this software
// without prior written permission. For written permission, please contact
// [EMAIL PROTECTED]
//
// 5. Products derived from this software may not be called "Apache", nor may
// "Apache" appear in their name, without prior written permission of the
// Apache Software Foundation.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
// DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// This software consists of voluntary contributions made by many individuals
// on behalf of the Apache Software Foundation. For more information on the
// Apache Software Foundation, please see <http://www.apache.org/>.
// ============================================================================
namespace Apache.Avalon.Container.Test.Components
{
using System;
using NUnit.Framework;
using Apache.Avalon.Framework;
/// <summary>
/// Definition for IBus service.
/// </summary>
public interface IBus : IVehicle
{
void Travel();
}
[AvalonService( typeof(IBus) )]
[AvalonComponent( "IBus", Lifestyle.Transient )]
public class Bus : Vehicle, IBus
{
public Bus()
{
}
public void Travel()
{
if (Engine == null)
{
throw new ApplicationException("We should have a
engine instance.");
}
if (Radio == null)
{
throw new ApplicationException("We should have a radio
instance.");
}
}
}
}
1.3 +5 -4
avalon-sandbox/avalon-net/cscontainer/Samples/bin/Samples/Samples.Components.dll
<<Binary file>>
1.3 +47 -24
avalon-sandbox/avalon-net/cscontainer/bin/Apache.Avalon.Container.Test.dll
<<Binary file>>
1.3 +387 -381
avalon-sandbox/avalon-net/cscontainer/bin/Apache.Avalon.Container.dll
<<Binary file>>
1.3 +6 -6
avalon-sandbox/avalon-net/cscontainer/bin/Apache.Avalon.Framework.dll
<<Binary file>>
1.2 +1 -1
avalon-sandbox/avalon-net/csframework/AvalonFramework/Attributes.cs
Index: Attributes.cs
===================================================================
RCS file:
/home/cvs/avalon-sandbox/avalon-net/csframework/AvalonFramework/Attributes.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Attributes.cs 22 Sep 2003 23:49:25 -0000 1.1
+++ Attributes.cs 27 Sep 2003 23:58:29 -0000 1.2
@@ -1 +1 @@
-// ============================================================================
// The Apache Software License, Version 1.1
// ============================================================================
//
// Copyright (C) 2002-2003 The Apache Software Foundation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modifica-
// tion, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. The end-user documentation included with the redistribution, if any, must
// include the following acknowledgment: "This product includes software
// developed by the Apache Software Foundation (http://www.apache.org/)."
// Alternately, this acknowledgment may appear in the software itself, if
// and wherever such third-party acknowledgments normally appear.
//
// 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
// must not be used to endorse or promote products derived from this software
// without prior written permission. For written permission, please contact
// [EMAIL PROTECTED]
//
// 5. Products derived from this software may not be called "Apache", nor may
// "Apache" appear in their name, without prior written permission of the
// Apache Software Foundation.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
// DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// This software consists of voluntary contributions made by many individuals
// on behalf of the Apache Software Foundation. For more information on the
// Apache Software Foundation, please see <http://www.apache.org/>.
// ============================================================================
namespace Apache.Avalon.Framework
{
using System;
///<summary>
/// Attribute used to mark the services that a component implements
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true,Inherited=false)]
public sealed class AvalonServiceAttribute : Attribute
{
private Type m_type;
///<summary>
/// Constructor to initialize the service's name.
///</summary>
///<param name="type">The type for the service</param>
///<exception cref="ArgumentException">If the "type" value is not an
interface</exception>
public AvalonServiceAttribute(Type type)
{
if (!type.IsInterface)
{
throw new ArgumentException(
"The type passed in does not represent an interface",
"type" );
}
m_type = type;
}
///<summary>
/// The name of the service
///</summary>
public Type ServiceType
{
get
{
return m_type;
}
}
}
/// <summary>
/// An enumeration used to mark a dependency as optional or not.
/// </summary>
public enum Optional
{
/// <summary>
/// Use "True" if the dependency is not required for the component
/// to run properly.
/// </summary>
True,
/// <summary>
/// Use "False" if the component will not work without the dependnecy.
/// </summary>
False
}
///<summary>
/// Attribute to mark the dependencies for a component.
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true,Inherited=false)]
public sealed class AvalonDependencyAttribute : Attribute
{
private Type m_type;
private bool m_optional;
private string m_name;
///<summary>
/// Constructor to initialize the dependency's name.
///</summary>
///<param name="type">The type for the dependency</param>
///<param name="key">The dependency's lookup key</param>
///<param name="optional">Whether or not the dependency is
optional</param>
///<exception cref="ArgumentException">If the "type" value is not an
interface</exception>
public AvalonDependencyAttribute(Type type, string key, Optional
optional)
{
if (!type.IsInterface)
{
throw new ArgumentException(
"The type passed in does not represent an interface",
"type" );
}
m_name = (null == key) ? type.Name : key;
m_optional = (optional == Optional.True);
m_type = type;
}
///<summary>
/// The lookup name of the dependency
///</summary>
public string Key
{
get
{
return m_name;
}
}
///<summary>
/// Is this dependency optional?
///</summary>
public bool IsOptional
{
get
{
return m_optional;
}
}
/// <summary>
/// The dependency type
/// </summary>
public Type DependencyType
{
get
{
return m_type;
}
}
}
/// <summary>
/// Enumeration used to mark the component's lifestyle.
/// </summary>
public enum Lifestyle
{
/// <summary>
/// Singleton components are instantiated once, and shared
/// between all clients.
/// </summary>
Singleton,
/// <summary>
/// Thread components have a unique instance per thread.
/// </summary>
Thread,
/// <summary>
/// Pooled components have a unique instance per client,
/// but they are managed in a pool.
/// </summary>
Pooled,
/// <summary>
/// Transient components are created on demand.
/// </summary>
Transient,
/// <summary>
/// Custom lifestyle components should be managed by custom component
factories.
/// </summary>
Custom
}
///<summary>
/// Attribute used to mark a component as an Avalon component.
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public sealed class AvalonComponentAttribute : Attribute
{
private Lifestyle m_lifestyle;
private string m_configName;
private string m_loggerName;
/// <summary>
/// Marks a class as a component, providing a configuration name and preferred
lifestyle
/// </summary>
/// <param name="name">The name used for configuration elements</param>
/// <param name="lifestyle">The lifestyle used for the component</param>
public AvalonComponentAttribute( string configName, Lifestyle
lifestyle )
{
m_lifestyle = lifestyle;
m_configName = configName;
}
/// <summary>
/// The configuration name assigned to this component.
/// </summary>
public string ConfigurationName
{
get
{
return m_configName;
}
}
/// <summary>
/// The logger name assigned to this component.
/// </summary>
public string LoggerName
{
get
{
return m_loggerName;
}
set
{
m_loggerName = value;
}
}
/// <summary>
/// The lifestyle associated with the component
/// </summary>
public Lifestyle Lifestyle
{
get
{
return m_lifestyle;
}
}
}
}
+// ============================================================================
// The Apache Software License, Version 1.1
// ============================================================================
//
// Copyright (C) 2002-2003 The Apache Software Foundation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modifica-
// tion, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. The end-user documentation included with the redistribution, if any, must
// include the following acknowledgment: "This product includes software
// developed by the Apache Software Foundation (http://www.apache.org/)."
// Alternately, this acknowledgment may appear in the software itself, if
// and wherever such third-party acknowledgments normally appear.
//
// 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
// must not be used to endorse or promote products derived from this software
// without prior written permission. For written permission, please contact
// [EMAIL PROTECTED]
//
// 5. Products derived from this software may not be called "Apache", nor may
// "Apache" appear in their name, without prior written permission of the
// Apache Software Foundation.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
// DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// This software consists of voluntary contributions made by many individuals
// on behalf of the Apache Software Foundation. For more information on the
// Apache Software Foundation, please see <http://www.apache.org/>.
// ============================================================================
namespace Apache.Avalon.Framework
{
using System;
///<summary>
/// Attribute used to mark the services that a component implements
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true,Inherited=false)]
public sealed class AvalonServiceAttribute : Attribute
{
private Type m_type;
///<summary>
/// Constructor to initialize the service's name.
///</summary>
///<param name="type">The type for the service</param>
///<exception cref="ArgumentException">If the "type" value is not an
interface</exception>
public AvalonServiceAttribute(Type type)
{
if (!type.IsInterface)
{
throw new ArgumentException(
"The type passed in does not represent an interface",
"type" );
}
m_type = type;
}
///<summary>
/// The name of the service
///</summary>
public Type ServiceType
{
get
{
return m_type;
}
}
}
/// <summary>
/// An enumeration used to mark a dependency as optional or not.
/// </summary>
public enum Optional
{
/// <summary>
/// Use "True" if the dependency is not required for the component
/// to run properly.
/// </summary>
True,
/// <summary>
/// Use "False" if the component will not work without the dependnecy.
/// </summary>
False
}
///<summary>
/// Attribute to mark the dependencies for a component.
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true,Inherited=true)]
public sealed class AvalonDependencyAttribute : Attribute
{
private Type m_type;
private bool m_optional;
private string m_name;
///<summary>
/// Constructor to initialize the dependency's name.
///</summary>
///<param name="type">The type for the dependency</param>
///<param name="key">The dependency's lookup key</param>
///<param name="optional">Whether or not the dependency is
optional</param>
///<exception cref="ArgumentException">If the "type" value is not an
interface</exception>
public AvalonDependencyAttribute(Type type, string key, Optional
optional)
{
if (!type.IsInterface)
{
throw new ArgumentException(
"The type passed in does not represent an interface",
"type" );
}
m_name = (null == key) ? type.Name : key;
m_optional = (optional == Optional.True);
m_type = type;
}
///<summary>
/// The lookup name of the dependency
///</summary>
public string Key
{
get
{
return m_name;
}
}
///<summary>
/// Is this dependency optional?
///</summary>
public bool IsOptional
{
get
{
return m_optional;
}
}
/// <summary>
/// The dependency type
/// </summary>
public Type DependencyType
{
get
{
return m_type;
}
}
}
/// <summary>
/// Enumeration used to mark the component's lifestyle.
/// </summary>
public enum Lifestyle
{
/// <summary>
/// Singleton components are instantiated once, and shared
/// between all clients.
/// </summary>
Singleton,
/// <summary>
/// Thread components have a unique instance per thread.
/// </summary>
Thread,
/// <summary>
/// Pooled components have a unique instance per client,
/// but they are managed in a pool.
/// </summary>
Pooled,
/// <summary>
/// Transient components are created on demand.
/// </summary>
Transient,
/// <summary>
/// Custom lifestyle components should be managed by custom component
factories.
/// </summary>
Custom
}
///<summary>
/// Attribute used to mark a component as an Avalon component.
///</summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public sealed class AvalonComponentAttribute : Attribute
{
private Lifestyle m_lifestyle;
private string m_configName;
private string m_loggerName;
/// <summary>
/// Marks a class as a component, providing a configuration name and preferred
lifestyle
/// </summary>
/// <param name="name">The name used for configuration elements</param>
/// <param name="lifestyle">The lifestyle used for the component</param>
public AvalonComponentAttribute( string configName, Lifestyle
lifestyle )
{
m_lifestyle = lifestyle;
m_configName = configName;
}
/// <summary>
/// The configuration name assigned to this component.
/// </summary>
public string ConfigurationName
{
get
{
return m_configName;
}
}
/// <summary>
/// The logger name assigned to this component.
/// </summary>
public string LoggerName
{
get
{
return m_loggerName;
}
set
{
m_loggerName = value;
}
}
/// <summary>
/// The lifestyle associated with the component
/// </summary>
public Lifestyle Lifestyle
{
get
{
return m_lifestyle;
}
}
}
}
1.3 +8 -10
avalon-sandbox/avalon-net/csframework/bin/Apache.Avalon.Framework.Test.dll
<<Binary file>>
1.3 +6 -6
avalon-sandbox/avalon-net/csframework/bin/Apache.Avalon.Framework.dll
<<Binary file>>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]