다음을 통해 공유


방법: 인스턴스 컨트롤 공급자 개발

다음 절차에서는 사용자 지정 인스턴스 제어 공급자를 만드는 단계에 대해 설명합니다.

  1. 클래스 라이브러리 프로젝트를 만듭니다.

  2. Microsoft.ApplicationServer.StoreManagement에 대한 참조를 추가합니다. 또한 System.Configuration 어셈블리에 대한 참조를 추가하여 이 항목의 샘플 코드를 컴파일합니다.

  3. 다음 문을 원본 파일의 시작 부분에 추가합니다.

    using Microsoft.ApplicationServer.StoreManagement.Control;
    using Microsoft.ApplicationServer.StoreManagement.Control;
    using System.Data.SqlClient;
    using System.Collections.Specialized;
    using System.Threading;
    using System.Data;
    
  4. InstanceControlProvider 클래스에서 파생되는 인스턴스 제어 공급자에 대한 클래스를 만듭니다.

        public class MySqlInstanceControlProvider : InstanceControlProvider
        {
        }
    
  5. Initialize 메서드를 구현합니다. 이 메서드는 구성 파일에 지정된 구성 정보에 해당하는 속성 모음을 적용합니다. 이 속성 모음의 데이터는 공급자를 구성하는 데 사용됩니다. Initialize 메서드는 CreateInstanceControl 또는 UniqueProviderIdentifier 메서드가 호출되기 이전에 호출됩니다.

    참고

    원격 시나리오에서 이름-값 컬렉션은 "EnableServiceModelMetadata"라는 항목을 포함합니다. 공급자는 base.Initialize 메서드를 호출하기 전에 이 매개 변수를 무시하고 제거하도록 선택할 수 있습니다. 이 속성은 일반적으로 Microsoft.Web.Administration.ServerManager 개체에서 SetMetadata(“ServiceModel”, true)를 호출할지 여부를 결정하는 데 사용됩니다.

    
            string ConnectionString { get; set; }
    
            public override void Initialize(string name, NameValueCollection config)
            {
    
                this.ConnectionString = config["connectionString"];
    
                // Initialize the base class
                base.Initialize(name, config);
            }
    
  6. InstanceControlProvider 개체의 CreateInstanceControl 메서드를 구현하여 사용자 지정 InstanceControl 개체를 반환합니다. 이 개체는 클라이언트가 CommandSend 개체 또는 CommandReceive 개체에 액세스하는 데 사용됩니다.

            public override InstanceControl CreateInstanceControl()
            {
                SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString);
                connectionStringBuilder.AsynchronousProcessing = true;
                return new MySqlInstanceControl(connectionStringBuilder.ConnectionString);
            }
    

    참고

    MySqlInstanceControl 형식 구현에 대해서는 다음 섹션을 참조하십시오.

  7. UniqueProviderIdentifier 메서드를 구현합니다. 이 메서드가 반환하는 고유 공급자 ID는 다른 공급자 개체가 동일한 기본 저장소에 확인되는지 여부를 결정하는 데 사용됩니다.

            string UniqueStoreIdentifier { get; set; }
    
            public override string UniqueProviderIdentifier()
            {   
                this.UniqueStoreIdentifier = GetUniqueStoreIdentifier(this.ConnectionString); 
                return this.UniqueStoreIdentifier;
            }
    
            private string GetUniqueStoreIdentifier(string connectionString)
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    using (SqlCommand command = new SqlCommand())
                    {
                        command.CommandType = System.Data.CommandType.Text;
                        command.CommandText = "SELECT TOP (1) [StoreIdentifier] FROM [Microsoft.ApplicationServer.DurableInstancing].[StoreVersion]";
                        command.Connection = connection;
    
                        command.Connection.Open();
    
                        Guid identifier = (Guid)command.ExecuteScalar();
                        return identifier.ToString();
                    }
                }
            }
    

Implementing InstanceControl

다음 절차에서는 사용자 지정 InstanceControl 형식을 만드는 단계에 대해 설명합니다.

  1. InstanceControl 클래스에서 파생되는 클래스를 만듭니다.

        public class MySqlInstanceControl : InstanceControl
        {
            readonly string connectionString;
             public MySqlInstanceControl(string connectionString)
             {
                 this.connectionString = connectionString;
             }
        }
    
  2. CommandReceive 속성을 구현합니다. CommandReceive 속성의 Get 접근자 메서드는 CommandReceive 개체를 반환해야 합니다. 클라이언트는 이 개체에 대해 메서드를 호출하여 명령 큐에서 명령을 비동기적으로 수신합니다.

            MySqlCommandReceive commandReceive;
            public override CommandReceive CommandReceive
            {
                get 
                {
                    if (this.commandReceive == null)
                    {
                        MySqlCommandReceive tmp = new MySqlCommandReceive(this.connectionString);
                        Interlocked.CompareExchange(ref this.commandReceive, tmp, null);
                    }
                    return this.commandReceive;
                }
            }
    
  3. CommandSend 속성을 구현하고 Get 접근자 메서드에서 사용자 지정 CommandSend 개체를 반환합니다. CommandSend 속성의 Get 메서드는 CommandSend 개체를 반환해야 합니다. 클라이언트는 이 개체의 메서드를 호출하여 명령 큐에 명령을 비동기적으로 보냅니다.

            MySqlCommandSend commandSend;
            public override CommandSend CommandSend
            {
                get
                {
                    if (this.commandSend == null)
                    {
                        MySqlCommandSend tmp = new MySqlCommandSend(this.connectionString);
                        Interlocked.CompareExchange(ref this.commandSend, tmp, null);
                        return this.commandSend;
                    }
                    return this.CommandSend;
                }
            }
    

    클라이언트는 이 두 개체를 사용하여 명령 큐에 명령을 보내고(큐에 삽입) 명령 큐에서 명령을 수신합니다(큐에서 제거). 예를 들어, 인스턴스 제어 cmdlet은 CommandSend 개체를 사용하여 명령 큐에 명령을 삽입하고 WMS(워크플로 관리 서비스)는 CommandReceive 개체를 사용하여 명령 큐에서 명령을 제거합니다. Remove-ASAppServiceInstance cmdlet이 실행될 때와 같이 저장소에서 명령을 직접 처리하여 인스턴스 저장소에서 인스턴스를 제거하는 경우도 있습니다.

    참고

    MySqlCommandSendMySqlCommandReceive 형식 구현에 대해서는 다음 섹션을 참조하십시오.

CommandSend 구현

사용자 지정 CommandSend 형식을 만들려면

  • CommandSend 클래스에서 파생되는 클래스를 만들고 BeginTrySendEndTrySend 메서드를 구현합니다.

        public class MySqlCommandSend : CommandSend
        {
            readonly string connectionString;
    
            public MySqlCommandSend(string connectionString)
            {
                this.connectionString = connectionString;
            }
    
            public override IAsyncResult BeginSend(InstanceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override void EndSend(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
        }
    

CommandReceive 구현

사용자 지정 CommandReceive 형식을 만들려면

  • CommandReceive 클래스에서 파생되는 클래스를 만들고 BeginTryReceiveEndTryReceive 메서드를 구현합니다.

        public class MySqlCommandReceive : CommandReceive
        {
            readonly string connectionString;
    
            Queue<MySqlReceivedInstanceCommand> receivedInstanceCommands;
    
            public MySqlCommandReceive(string connectionString)
            {
                this.connectionString = connectionString;
                this.receivedInstanceCommands = new Queue<MySqlReceivedInstanceCommand>();          
            }
    
            public override IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override bool EndTryReceive(IAsyncResult result, out ReceivedInstanceCommand command)
            {
                throw new NotImplementedException();
            }
        }
    

    참고

    MySqlReceivedInstanceCommand 클래스 구현에 대해서는 다음 섹션을 참조하십시오.

ReceivedInstanceCommand 구현

사용자 지정 ReceivedInstanceCommand 형식을 만들려면

  • ReceivedInstanceCommand 클래스에서 파생되는 클래스를 만들고 InstanceCommandContext 속성을 구현합니다.

        class MySqlReceivedInstanceCommand : ReceivedInstanceCommand
        {
            long commandId;
            MySqlCommandReceive receiver;
            MySqlInstanceCommandContext context;
    
            internal MySqlReceivedInstanceCommand(long commandId,
                 Guid instanceId, Microsoft.ApplicationServer.StoreManagement.Control.CommandType commandType, IDictionary<string, string> serviceIdentifier, TimeSpan timeout,
                MySqlCommandReceive receiver) : base()
            {
                this.commandId = commandId;
                base.CommandType = commandType;
                base.InstanceId = instanceId;
                base.ServiceIdentifier = serviceIdentifier;
                //this.CommandTimeout = new TimeoutHelper(timeout, true);
                this.receiver = receiver;
                this.context = new MySqlInstanceCommandContext(this);
            }
            public override InstanceCommandContext InstanceCommandContext
            {
                get
                {
                    return this.context;
                }
            }
        }
    

    참고

    MySqlInstanceCommandContext 형식 구현에 대해서는 다음 섹션을 참조하십시오.

InstanceCommandContext 구현

사용자 지정 InstanceCommandContext 형식을 만들려면

  • InstanceCommandContext 클래스에서 파생되는 클래스를 만들고 BeginComplete, EndComplete, BeginAbandonEndAbandon 메서드를 구현합니다.

    클라이언트는 InstanceCommandContext 개체의 BeginComplete 메서드를 호출하여 명령 실행이 성공했음을 알립니다. 그런 다음 제어 공급자는 명령 큐에서 명령을 제거합니다. WMS는 명령 실행이 성공한 경우 이 메서드를 호출합니다.

    클라이언트는 InstanceCommandContext 개체의 BeginAbandon 메서드를 호출하여 명령 실행이 실패했음을 알립니다. 명령으로 수행할 작업은 인스턴스 제어 공급자가 결정해야 합니다. 예를 들어, 제어 공급자는 명령 큐에서 명령을 제거하기 전에 특정 횟수 동안 명령을 다시 시도할 수 있습니다. WMS는 명령 실행이 실패한 경우 이 메서드를 호출합니다.

        class MySqlInstanceCommandContext : InstanceCommandContext
        {
            MySqlReceivedInstanceCommand command;
    
            internal MySqlInstanceCommandContext(MySqlReceivedInstanceCommand command)
            {
                this.command = command;
            }
    
            public override IAsyncResult BeginAbandon(Exception exception, TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override IAsyncResult BeginComplete(TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override void EndAbandon(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
    
            public override void EndComplete(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
        }
    

참고 항목

개념

방법: 인스턴스 저장소 공급자 개발
방법: 인스턴스 쿼리 공급자 개발
방법: 인스턴스 저장소, 쿼리 및 컨트롤 공급자 구성
인스턴스 저장소, 쿼리 및 제어 공급자

  2011-12-05